• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/transmission/transmission-2.73/third-party/libutp/
1#ifndef __TEMPLATES_H__
2#define __TEMPLATES_H__
3
4#include "utypes.h"
5#include <assert.h>
6
7#if defined(POSIX)
8/* Allow over-writing FORCEINLINE from makefile because gcc 3.4.4 for buffalo
9   doesn't seem to support __attribute__((always_inline)) in -O0 build
10   (strangely, it works in -Os build) */
11#ifndef FORCEINLINE
12// The always_inline attribute asks gcc to inline the function even if no optimization is being requested.
13// This macro should be used exclusive-or with the inline directive (use one or the other but not both)
14// since Microsoft uses __forceinline to also mean inline,
15// and this code is following a Microsoft compatibility model.
16// Just setting the attribute without also specifying the inline directive apparently won't inline the function,
17// as evidenced by multiply-defined symbols found at link time.
18#define FORCEINLINE inline __attribute__((always_inline))
19#endif
20#endif
21
22#ifdef __GNUC__
23// Used for gcc tool chains accepting but not supporting pragma pack
24// See http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
25#define PACKED_ATTRIBUTE __attribute__((__packed__))
26#else
27#define PACKED_ATTRIBUTE
28#endif
29
30// Utility templates
31#undef min
32#undef max
33
34template <typename T> static inline T min(T a, T b) { if (a < b) return a; return b; }
35template <typename T> static inline T max(T a, T b) { if (a > b) return a; return b; }
36
37template <typename T> static inline T min(T a, T b, T c) { return min(min(a,b),c); }
38template <typename T> static inline T max(T a, T b, T c) { return max(max(a,b),c); }
39template <typename T> static inline T clamp(T v, T mi, T ma)
40{
41	if (v > ma) v = ma;
42	if (v < mi) v = mi;
43	return v;
44}
45
46#if (defined(__SVR4) && defined(__sun))
47#pragma pack(1)
48#else
49#pragma pack(push,1)
50#endif
51
52namespace aux
53{
54	FORCEINLINE uint16 host_to_network(uint16 i) { return htons(i); }
55	FORCEINLINE uint32 host_to_network(uint32 i) { return htonl(i); }
56	FORCEINLINE int32 host_to_network(int32 i) { return htonl(i); }
57	FORCEINLINE uint16 network_to_host(uint16 i) { return ntohs(i); }
58	FORCEINLINE uint32 network_to_host(uint32 i) { return ntohl(i); }
59	FORCEINLINE int32 network_to_host(int32 i) { return ntohl(i); }
60}
61
62template <class T>
63struct PACKED_ATTRIBUTE big_endian
64{
65	T operator=(T i) { m_integer = aux::host_to_network(i); return i; }
66	operator T() const { return aux::network_to_host(m_integer); }
67private:
68	T m_integer;
69};
70
71typedef big_endian<int32> int32_big;
72typedef big_endian<uint32> uint32_big;
73typedef big_endian<uint16> uint16_big;
74
75#if (defined(__SVR4) && defined(__sun))
76#pragma pack(0)
77#else
78#pragma pack(pop)
79#endif
80
81template<typename T> static inline void zeromem(T *a, size_t count = 1) { memset(a, 0, count * sizeof(T)); }
82
83typedef int SortCompareProc(const void *, const void *);
84
85template<typename T> static FORCEINLINE void QuickSortT(T *base, size_t num, int (*comp)(const T *, const T *)) { qsort(base, num, sizeof(T), (SortCompareProc*)comp); }
86
87
88// WARNING: The template parameter MUST be a POD type!
89template <typename T, size_t minsize = 16> class Array {
90protected:
91	T *mem;
92	size_t alloc,count;
93
94public:
95	Array(size_t init) { Init(init); }
96	Array() { Init(); }
97	~Array() { Free(); }
98
99	void inline Init() { mem = NULL; alloc = count = 0; }
100	void inline Init(size_t init) { Init(); if (init) Resize(init); }
101	size_t inline GetCount() const { return count; }
102	size_t inline GetAlloc() const { return alloc; }
103	void inline SetCount(size_t c) { count = c; }
104
105	inline T& operator[](size_t offset) { assert(offset ==0 || offset<alloc); return mem[offset]; }
106	inline const T& operator[](size_t offset) const { assert(offset ==0 || offset<alloc); return mem[offset]; }
107
108	void inline Resize(size_t a) {
109		if (a == 0) { free(mem); Init(); }
110		else { mem = (T*)realloc(mem, (alloc=a) * sizeof(T)); }
111	}
112
113	void Grow() { Resize(::max<size_t>(minsize, alloc * 2)); }
114
115	inline size_t Append(const T &t) {
116		if (count >= alloc) Grow();
117		size_t r=count++;
118		mem[r] = t;
119		return r;
120	}
121
122	T inline &Append() {
123		if (count >= alloc) Grow();
124		return mem[count++];
125	}
126
127	void inline Compact() {
128		Resize(count);
129	}
130
131	void inline Free() {
132		free(mem);
133		Init();
134	}
135
136	void inline Clear() {
137		count = 0;
138	}
139
140	bool inline MoveUpLast(size_t index) {
141		assert(index < count);
142		size_t c = --count;
143		if (index != c) {
144			mem[index] = mem[c];
145			return true;
146		}
147		return false;
148	}
149
150	bool inline MoveUpLastExist(const T &v) {
151		return MoveUpLast(LookupElementExist(v));
152	}
153
154	size_t inline LookupElement(const T &v) const {
155		for(size_t i = 0; i != count; i++)
156			if (mem[i] == v)
157				return i;
158		return (size_t) -1;
159	}
160
161	bool inline HasElement(const T &v) const {
162		return LookupElement(v) != -1;
163	}
164
165	typedef int SortCompareProc(const T *a, const T *b);
166
167	void Sort(SortCompareProc* proc, size_t start, size_t end) {
168		QuickSortT(&mem[start], end - start, proc);
169	}
170
171	void Sort(SortCompareProc* proc, size_t start) {
172		Sort(proc, start, count);
173	}
174
175	void Sort(SortCompareProc* proc) {
176		Sort(proc, 0, count);
177	}
178};
179
180#endif //__TEMPLATES_H__
181