fastdo  0.6.16
utilities.hpp
浏览该文件的文档.
1 #ifndef __UTILITIES_HPP__
2 #define __UTILITIES_HPP__
3 //
4 // utilities 提供基础的宏,模板,类,函数
5 //
6 
7 // 各平台条件编译宏检测
8 #include "system_detection.inl"
9 
10 #if _MSC_VER > 0 && _MSC_VER < 1201
11 #pragma warning( disable: 4786 )
12 #endif
13 #if _MSC_VER > 0
14 #pragma warning( disable : 4996 )
15 #endif
16 
17 #include <string>
18 #include <sstream>
19 #include <vector>
20 #include <map>
21 #include <tuple>
22 #include <queue>
23 #include <functional>
24 #include <algorithm>
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #if defined(OS_WIN)
30 #include <windows.h>
31 #endif
32 
34 namespace winux
35 {
36 // 一些宏定义 ----------------------------------------------------------------------------------
37 /* Dll相关宏定义:
38  WINUX_DLL_USE - 此宏开关表示有DLL参与,包括生成DLL或者导入DLL,不定义此宏和一般的使用源码没区别
39  WINUX_DLL_EXPORTS - 此宏开关表示是生成DLL(dllexport)还是导入DLL(dllimport),linux平台下忽略
40  WINUX_DLL - 标记函数、类、变量,用于标明其要从DLL导出还是导入,linux平台下忽略
41  WINUX_API - 标记函数调用约定,Win下Dll参与时为stdcall,否则为空白默认,linux平台下忽略
42  WINUX_FUNC_DECL - 标记函数声明
43  WINUX_FUNC_IMPL - 标记函数实现 */
44 #ifdef WINUX_DLL_USE
45  #if defined(_MSC_VER) || defined(WIN32)
46  #pragma warning( disable: 4251 )
47  #pragma warning( disable: 4275 )
48  #ifdef WINUX_DLL_EXPORTS
49  #define WINUX_DLL __declspec(dllexport)
50  #else
51  #define WINUX_DLL __declspec(dllimport)
52  #endif
53 
54  #define WINUX_API __stdcall
55  #else
56  #define WINUX_DLL
57  #define WINUX_API
58  #endif
59 #else
60  #define WINUX_DLL
61  #define WINUX_API
62 #endif
63 
64 #define WINUX_FUNC_DECL(ret) WINUX_DLL ret WINUX_API
65 #define WINUX_FUNC_IMPL(ret) ret WINUX_API
66 
67 #ifndef countof
68  #define countof(arr) ( sizeof(arr) / sizeof(arr[0]) )
69 #endif
70 
71 #if !defined($T)
72  #if defined(_UNICODE) || defined(UNICODE)
73  #define $T(__x) L##__x
74  #else
75  #define $T(__x) __x
76  #endif
77 #endif
78 
79 #ifndef interface
80 #define interface struct
81 #endif
82 
83 // 禁止类的对象赋值/拷贝构造
84 // DISABLE_OBJECT_COPY
85 #define DISABLE_OBJECT_COPY( clsname ) private:\
86 clsname( clsname const & ) = delete;\
87 clsname & operator = ( clsname const & ) = delete;
88 
89 // 如果指针非NULL
90 // IF_PTR
91 #define IF_PTR(ptr) if ( (ptr) != NULL ) (ptr)
92 // ASSIGN_PTR
93 #define ASSIGN_PTR(ptr) if ( (ptr) != NULL ) (*(ptr))
94 
95 // 不使用一个变量
96 #ifndef UNUSED
97 #define UNUSED(s)
98 #endif
99 
100 // 给类添加一个属性和相关的数据成员,自动添加get/set方法
101 #define DEFINE_ATTR_MEMBER( ty, name, memname ) \
102 public:\
103  ty const & get##name() const { return this->memname; }\
104  void set##name( ty const & v ) { this->memname = v; }\
105 private:\
106  ty memname;
108 // 给类添加一个只读属性和相关的数据成员,自动添加get方法
109 #define DEFINE_ATTR_MEMBER_READONLY( ty, name, memname ) \
110 public:\
111  ty const & get##name() const { return this->memname; }\
112 private:\
113  ty memname;
114 
115 // 给类添加一个属性和相关的数据成员,自动添加get/set方法
116 #define DEFINE_ATTR_MEMBER_VAL( ty, name, memname ) \
117 public:\
118  ty get##name() const { return this->memname; }\
119  void set##name( ty v ) { this->memname = v; }\
120 private:\
121  ty memname;
122 
123 // 给类添加一个只读属性和相关的数据成员,自动添加get方法
124 #define DEFINE_ATTR_MEMBER_VAL_READONLY( ty, name, memname ) \
125 public:\
126  ty get##name() const { return this->memname; }\
127 private:\
128  ty memname;
129 
130 // 给类添加一个属性的get/set方法
131 #define DEFINE_ATTR_METHOD( ty, name, memname ) \
132 public:\
133  ty const & get##name() const { return this->memname; }\
134  void set##name( ty const & v ) { this->memname = v; }
135 
136 // 给类添加一个属性的get方法
137 #define DEFINE_ATTR_METHOD_READONLY( ty, name, memname ) \
138 public:\
139  ty const & get##name() const { return this->memname; }
140 
141 // 给类添加一个属性的get/set方法
142 #define DEFINE_ATTR_METHOD_VAL( ty, name, memname ) \
143 public:\
144  ty get##name() const { return this->memname; }\
145  void set##name( ty v ) { this->memname = v; }
146 
147 // 给类添加一个属性的get方法
148 #define DEFINE_ATTR_METHOD_VAL_READONLY( ty, name, memname ) \
149 public:\
150  ty get##name() const { return this->memname; }
151 
152 // 给类添加一个属性,自动添加get/set方法,需提供实现
153 #define DEFINE_ATTR( ty, name, getcode, setcode ) \
154 public:\
155  ty const & get##name() const { getcode; }\
156  void set##name( ty const & _VAL_ ) { setcode; }
157 
158 // 给类添加一个只读属性,自动添加get方法,需提供实现
159 #define DEFINE_ATTR_READONLY( ty, name, getcode ) \
160 public:\
161  ty const & get##name() const { getcode; }
162 
163 // 给类添加一个属性,自动添加get/set方法,需提供实现
164 #define DEFINE_ATTR_VAL( ty, name, getcode, setcode ) \
165 public:\
166  ty get##name() const { getcode; }\
167  void set##name( ty _VAL_ ) { setcode; }
168 
169 // 给类添加一个只读属性,自动添加get方法,需提供实现
170 #define DEFINE_ATTR_VAL_READONLY( ty, name, getcode ) \
171 public:\
172  ty get##name() const { getcode; }
173 
174 // 给类定义一个NewInstance静态方法
175 #define DEFINE_FUNC_NEWINSTANCE( cls, ret, paramtypes, params ) \
176 inline static ret * NewInstance##paramtypes \
177 { \
178  return new cls##params;\
179 }
180 
181 // 给类定义一个自定义事件相关的成员和函数,默认实现
182 #define DEFINE_CUSTOM_EVENT(evtname, paramtypes, calledparams) \
183 public: \
184  using evtname##HandlerFunction = std::function< void paramtypes >; \
185  void on##evtname##Handler( evtname##HandlerFunction handler ) \
186  { \
187  this->_##evtname##Handler = handler; \
188  } \
189 protected: \
190  evtname##HandlerFunction _##evtname##Handler; \
191  virtual void on##evtname paramtypes \
192  { \
193  if ( this->_##evtname##Handler ) this->_##evtname##Handler calledparams; \
194  }
195 
196 // 给类定义一个自定义事件相关的成员和函数,带返回值并自己实现
197 #define DEFINE_CUSTOM_EVENT_RETURN_EX(ret, evtname, paramtypes) \
198 public: \
199  using evtname##HandlerFunction = std::function< ret paramtypes >; \
200  void on##evtname##Handler( evtname##HandlerFunction handler ) \
201  { \
202  this->_##evtname##Handler = handler; \
203  } \
204 protected: \
205  evtname##HandlerFunction _##evtname##Handler; \
206  virtual ret on##evtname paramtypes
207 
208 
209 // 判断GCC版本大于给定版本
210 #define GCC_VERSION_GREAT_THAN(Major,Minor,Patchlevel) \
211 ( __GNUC__ > Major || ( __GNUC__ == Major && ( __GNUC_MINOR__ > Minor || ( __GNUC_MINOR__ == Minor && __GNUC_PATCHLEVEL__ > Patchlevel ) ) ) )
212 
213 // WINUX基本类型 -----------------------------------------------------------------------------------
214 typedef int int32;
215 typedef unsigned int uint, uint32;
216 typedef unsigned long ulong;
217 typedef short int16;
218 typedef unsigned short ushort, uint16;
219 typedef char int8;
220 typedef unsigned char uint8;
221 
222 typedef char16_t char16;
223 typedef char32_t char32;
224 
225 typedef intptr_t offset_t, ssize_t;
226 typedef size_t usize_t;
227 
228 #if defined(CL_VC)
229 typedef wchar_t wchar;
230 typedef unsigned __int64 uint64;
231 typedef unsigned __int64 ulonglong;
232 typedef __int64 int64;
233 typedef __int64 longlong;
234 #else
235 typedef wchar_t wchar;
236 typedef unsigned long long uint64;
237 typedef unsigned long long ulonglong;
238 typedef long long int64;
239 typedef long long longlong;
240 #endif
241 
242 #if defined(_UNICODE) || defined(UNICODE)
243 typedef wchar tchar;
244 #else
245 typedef char tchar;
246 #endif
247 
248 #ifndef byte
249 typedef unsigned char byte;
250 #endif
251 
252 class Mixed;
253 // STL wrappers
254 template < typename _ChTy >
255 using XString = std::basic_string< _ChTy, std::char_traits<_ChTy>, std::allocator<_ChTy> >;
256 
262 
263 template < typename _ChTy >
264 using XStringArray = std::vector< XString<_ChTy> >;
265 
273 
274 typedef std::map<String, String> StringStringMap;
275 typedef std::pair<String, String> StringStringPair;
276 
277 typedef std::vector<Mixed> MixedArray;
278 typedef std::map<String, Mixed> StringMixedMap;
279 typedef std::pair<String, Mixed> StringMixedPair;
280 //typedef std::map<Mixed, Mixed> MixedMixedMap;
281 //typedef std::pair<Mixed, Mixed> MixedMixedPair;
282 
283 // WINUX常用常量 ---------------------------------------------------------------------------
285 static constexpr size_t const npos = static_cast<size_t>(-1);
287 extern WINUX_DLL Mixed const mxNull;
288 // 字符串相关字面常量
289 #include "literal_str.inl"
290 
291 // 模板元编程支持 ---------------------------------------------------------------------------
293 template < typename _ChTy > struct CharSpec {};
294 template <> struct CharSpec<char> { using Type = char; };
295 template <> struct CharSpec<wchar> { using Type = wchar; };
296 template <> struct CharSpec<char16> { using Type = char16; };
297 template <> struct CharSpec<char32> { using Type = char32; };
298 
300 template < typename _ChTy >
302 
304 template < uint64 n > struct Bin0
305 {
306  enum : uint64 { val = ( Bin0< n / 8 >::val << 1 ) + n % 8 };
307 };
308 template <> struct Bin0<0>
309 {
310  enum : uint64 { val = 0 };
311 };
312 
313 // 二进制数 macro包装
314 #define BinVal(x) winux::Bin0<0##x>::val
315 
316 // 引用参数包装
317 template < typename _Ty >
318 class RefParam
319 {
320  _Ty & _r;
321 public:
322  typedef _Ty ParamType;
323  typedef _Ty & ParamTypeRef;
324 
325  explicit RefParam( ParamTypeRef r ) : _r(r) { }
326  operator ParamTypeRef () { return _r; }
327 };
328 
330 template < typename _Ty >
331 inline RefParam<_Ty> Ref( _Ty & r )
332 {
333  return RefParam<_Ty>(r);
334 }
335 
337 template < size_t... _Index >
338 struct IndexSequence { };
339 
340 // 构建一个IndexSequence< 0, 1, 2, ..., _Num - 1 >
341 template < size_t _Num, typename _IdxSeq = IndexSequence<> >
343 
344 template < size_t _Num, size_t... _Index >
345 struct MakeIndexSequence< _Num, IndexSequence<_Index...> > : MakeIndexSequence< _Num - 1, IndexSequence< _Index..., sizeof...(_Index) > > { };
346 
347 template < size_t... _Index >
348 struct MakeIndexSequence< 0, IndexSequence<_Index...> >
349 {
350  using Type = IndexSequence<_Index...>;
351 };
352 
354 #include "func_traits.inl"
355 
357 #include "func_runable.inl"
358 
360 #include "func_invoker.inl"
361 
363 template < typename _PfnType, _PfnType pfn >
365 {
366  template < typename... _ArgType >
367  static typename FuncTraits<_PfnType>::ReturnType func( _ArgType&& ...arg )
368  {
369  return (*pfn)( std::forward<_ArgType>(arg)... );
370  }
371 };
372 
374 template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
376 {
377 public:
378  typedef std::map< _KTy, _VTy, _Pr, _Alloc > MapType;
379 
380  MapAssigner( MapType * m ) : _m(m) { }
381  MapAssigner & operator () ( _KTy const & k, _VTy const & v )
382  {
383  (*_m)[k] = v;
384  return *this;
385  }
386  operator MapType & () { return *_m; }
387 
388 private:
389  MapType * _m;
390 };
391 
393 template < typename _Ty, typename _Alloc >
395 {
396 public:
397  typedef std::vector< _Ty, _Alloc > VectorType;
398 
399  ArrayAssigner( VectorType * a ) : _a(a) { }
400  ArrayAssigner & operator () ( _Ty const & v )
401  {
402  _a->push_back(v);
403  return *this;
404  }
405  operator VectorType & () { return *_a; }
406 
407 private:
408  VectorType * _a;
409 };
410 
412 template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
413 inline MapAssigner< _KTy, _VTy, _Pr, _Alloc > Assign( std::map< _KTy, _VTy, _Pr, _Alloc > * m )
414 {
416 }
417 
419 template < typename _Ty, typename _Alloc >
420 inline ArrayAssigner<_Ty, _Alloc> Assign( std::vector<_Ty, _Alloc> * a )
421 {
422  return ArrayAssigner<_Ty, _Alloc>(a);
423 }
424 
426 template < typename _TargetCls >
427 class Members
428 {
429 public:
430  Members() : _p(nullptr)
431  {
432  this->_create();
433  }
434 
435  template < typename... _ArgType >
436  Members( _ArgType&&... arg ) : _p(nullptr)
437  {
438  this->_create( std::forward<_ArgType>(arg)... );
439  }
440 
442  {
443  this->_destroy();
444  }
445 
446  Members( Members const & other ) : _p(nullptr)
447  {
448  this->_create();
449  *_p = *other._p;
450  }
452  Members & operator = ( Members const & other )
453  {
454  if ( &other != this )
455  {
456  *_p = *other._p;
457  }
458  return *this;
459  }
460 
461 #ifndef MOVE_SEMANTICS_DISABLED
462  Members( Members && other ) : _p(nullptr)
463  {
464  _p = other._p;
465  other._p = nullptr;
466  }
468  Members & operator = ( Members && other )
469  {
470  if ( &other != this )
471  {
472  this->_destroy();
473  _p = other._p;
474  other._p = nullptr;
475  }
476  return *this;
477  }
478 #endif
479 
480  _TargetCls * get()
481  {
482  return _p;
483  }
484  _TargetCls * get() const
485  {
486  return _p;
487  }
488 
489  _TargetCls * operator -> ()
490  {
491  return _p;
492  }
493  _TargetCls const * operator -> () const
494  {
495  return _p;
496  }
497 
498  operator _TargetCls & ()
499  {
500  return *_p;
501  }
502  operator _TargetCls const & () const
503  {
504  return *_p;
505  }
506 
507  operator bool() const
508  {
509  return _p != nullptr;
510  }
511 
512 private:
514  void _destroy()
515  {
516  if ( _p )
517  {
518  delete (_TargetCls *)_p;
519  _p = nullptr;
520  }
521  }
522 
524  template < typename... _ArgType >
525  void _create( _ArgType&&... arg )
526  {
527  this->_destroy();
528  _p = new _TargetCls( std::forward<_ArgType>(arg)... );
529  }
530 
531  _TargetCls * _p;
532 };
533 
535 template < typename _TargetCls, size_t _MembersSize >
537 {
538 public:
540  {
541  this->_create<sizeof(_TargetCls)>();
542  }
543 
544  template < typename... _ArgType >
545  PlainMembers( _ArgType&&... arg )
546  {
547  this->_create<sizeof(_TargetCls)>( std::forward<_ArgType>(arg)... );
548  }
549 
551  {
552  this->_destroy();
553  }
554 
555  PlainMembers( PlainMembers const & other )
556  {
557  this->_create<sizeof(_TargetCls)>();
558  *this->get() = *other.get();
559  }
561  PlainMembers & operator = ( PlainMembers const & other )
562  {
563  if ( &other != this )
564  {
565  *this->get() = *other.get();
566  }
567  return *this;
568  }
569 
570 #ifndef MOVE_SEMANTICS_DISABLED
572  {
573  this->_create<sizeof(_TargetCls)>();
574  *this->get() = std::move( *other.get() );
575  }
577  PlainMembers & operator = ( PlainMembers && other )
578  {
579  if ( &other != this )
580  {
581  *this->get() = std::move( *other.get() );
582  }
583  return *this;
584  }
585 #endif
586 
587  _TargetCls * get()
588  {
589  return reinterpret_cast<_TargetCls*>((char*)_block);
590  }
591  _TargetCls * get() const
592  {
593  return reinterpret_cast<_TargetCls*>((char*)_block);
594  }
595 
596  _TargetCls * operator -> ()
597  {
598  return this->get();
599  }
600  _TargetCls const * operator -> () const
601  {
602  return this->get();
603  }
604 
605  operator _TargetCls & ()
606  {
607  return *this->get();
608  }
609  operator _TargetCls const & () const
610  {
611  return *this->get();
612  }
613 
614  operator bool() const
615  {
616  return _MembersSize >= sizeof(_TargetCls);
617  }
618 
619 private:
621  void _destroy()
622  {
623  this->get()->~_TargetCls();
624  }
625 
627  template < size_t _TargetClsSize, typename... _ArgType >
628  void _create( _ArgType&&... arg )
629  {
630  static_assert( !( _TargetClsSize > _MembersSize ), "Error: sizeof(_TargetCls) > _MembersSize, _MembersSize is too small" );
631  new(_block) _TargetCls( std::forward<_ArgType>(arg)... );
632  }
633 
634  char _block[_MembersSize];
635 };
636 
637 // 一些函数模板和函数 ------------------------------------------------------------------------
639 template < typename _ChTy, typename = CharTypeConstrain<_ChTy> >
640 inline static size_t StrLen( _ChTy const * str )
641 {
642  size_t len = 0;
643  while ( str[len] ) len++;
644  return len;
645 }
646 
648 template < typename _Ty >
649 inline static _Ty InvertByteOrder( _Ty v )
650 {
651  _Ty v2 = 0;
652  for ( int i = 0; i < sizeof(_Ty); ++i ) v2 |= ( ( v >> i * 8 ) & 0xFFU ) << ( sizeof(_Ty) - 1 - i ) * 8;
653  return v2;
654 }
655 
657 template < typename _Ty >
658 inline static void InvertByteOrderArray( _Ty * p, size_t count )
659 {
660  for ( size_t k = 0; k < count; k++ )
661  {
662  p[k] = InvertByteOrder(p[k]);
663  }
664 }
665 
667 WINUX_FUNC_DECL(void) InvertByteOrder( void * buf, size_t size );
668 
670 inline static bool IsLittleEndian()
671 {
672  constexpr winux::uint16 judgeHostOrder = 0x0102;
673  return *(winux::byte*)&judgeHostOrder == 0x02;
674 }
675 
677 inline static bool IsBigEndian()
678 {
679  constexpr winux::uint16 judgeHostOrder = 0x0102;
680  return *(winux::byte*)&judgeHostOrder == 0x01;
681 }
682 
684 WINUX_FUNC_DECL(int) MemoryCompare( void const * buf1, size_t n1, void const * buf2, size_t n2 );
685 
687 WINUX_FUNC_DECL(int) MemoryCompareI( void const * buf1, size_t n1, void const * buf2, size_t n2 );
688 
690 template < typename _ChTy >
691 inline static int StringCompare( XString<_ChTy> const & str1, XString<_ChTy> const & str2 )
692 {
693  size_t n = str1.length() < str2.length() ? str1.length() : str2.length();
694  for ( size_t i = 0; i < n; ++i )
695  {
696  int diff = str1[i] - str2[i];
697  if ( diff != 0 ) return diff;
698  }
699  return (int)( str1.length() - str2.length() );
700 }
701 
703 template < typename _ChTy >
704 inline static int StringCompareI( XString<_ChTy> const & str1, XString<_ChTy> const & str2 )
705 {
706  size_t n = str1.length() < str2.length() ? str1.length() : str2.length();
707  for ( size_t i = 0; i < n; ++i )
708  {
709  int diff = tolower(str1[i]) - tolower(str2[i]);
710  if ( diff != 0 ) return diff;
711  }
712  return (int)( str1.length() - str2.length() );
713 }
714 
716 template < typename _Ty >
717 inline static bool ArrayLess( _Ty const * arr1, size_t count1, _Ty const * arr2, size_t count2 )
718 {
719  size_t n = count1 < count2 ? count1 : count2;
720  size_t i;
721  for ( i = 0; i < n; ++i )
722  {
723  if ( arr1[i] != arr2[i] ) break;
724  }
725  if ( i < n )
726  {
727  return arr1[i] < arr2[i];
728  }
729  else // i == n
730  {
731  return count1 < count2;
732  }
733 }
734 
736 template < typename _Ty >
737 inline static bool ArrayGreater( _Ty const * arr1, size_t count1, _Ty const * arr2, size_t count2 )
738 {
739  size_t n = count1 < count2 ? count1 : count2;
740  size_t i;
741  for ( i = 0; i < n; ++i )
742  {
743  if ( arr1[i] != arr2[i] ) break;
744  }
745  if ( i < n )
746  {
747  return arr1[i] > arr2[i];
748  }
749  else // i == n
750  {
751  return count1 > count2;
752  }
753 }
754 
756 template < typename _Ty >
757 inline static bool ArrayEqual( _Ty const * arr1, size_t count1, _Ty const * arr2, size_t count2 )
758 {
759  size_t n = count1 < count2 ? count1 : count2;
760  for ( size_t i = 0; i < n; ++i )
761  {
762  if ( arr1[i] != arr2[i] ) return false;
763  }
764  return count1 == count2;
765 }
766 
768 template < typename _Ty >
769 inline static bool ArrayLess( std::vector<_Ty> const & arr1, std::vector<_Ty> const & arr2 )
770 {
771  auto p1 = arr1.empty() ? nullptr : &arr1.front();
772  auto p2 = arr2.empty() ? nullptr : &arr2.front();
773  return ArrayLess( p1, arr1.size(), p2, arr2.size() );
774 }
775 
777 template < typename _Ty >
778 inline static bool ArrayGreater( std::vector<_Ty> const & arr1, std::vector<_Ty> const & arr2 )
779 {
780  auto p1 = arr1.empty() ? nullptr : &arr1.front();
781  auto p2 = arr2.empty() ? nullptr : &arr2.front();
782  return ArrayGreater( p1, arr1.size(), p2, arr2.size() );
783 }
784 
786 template < typename _Ty >
787 inline static bool ArrayEqual( std::vector<_Ty> const & arr1, std::vector<_Ty> const & arr2 )
788 {
789  auto p1 = arr1.empty() ? nullptr : &arr1.front();
790  auto p2 = arr2.empty() ? nullptr : &arr2.front();
791  return ArrayEqual( p1, arr1.size(), p2, arr2.size() );
792 }
793 
794 class Collection;
795 
797 WINUX_FUNC_DECL(bool) CollectionLess( Collection const & coll1, Collection const & coll2 );
798 
800 WINUX_FUNC_DECL(bool) CollectionGreater( Collection const & coll1, Collection const & coll2 );
801 
803 WINUX_FUNC_DECL(bool) CollectionEqual( Collection const & coll1, Collection const & coll2 );
804 
806 template < typename _MAP, typename _KEY >
807 inline bool isset( _MAP const & m, _KEY const & k )
808 {
809  return m.find(k) != m.end();
810 }
811 
813 template < typename _Ty >
814 inline std::vector<_Ty> ToArray( _Ty * arr, uint count )
815 {
816  return std::vector<_Ty>( arr, arr + count );
817 }
818 
819 template < typename _Ty, uint _Count >
820 inline std::vector<_Ty> ToArray( _Ty (&arr)[_Count] )
821 {
822  return std::vector<_Ty>( arr, arr + _Count );
823 }
824 
828 template < typename _Fx, typename... _ArgType >
829 inline int VoidReturnInt( _Fx fn, _ArgType&& ...arg )
830 {
831  fn( std::forward<_ArgType>(arg)... );
832  return 1;
833 }
834 
835 // ----------------------------------------------------------------------------------------
836 
838 class Error : public std::exception
839 {
840 public:
841  enum
842  {
843  // 错误号详见errno.h: EXXXX
844  };
845 
846  Error() throw() : _errType(0) { }
847  Error( int errType, AnsiString const & errStr ) throw() : _errType(errType), _errStr(errStr) { }
848  virtual ~Error() throw() { }
849  virtual int getErrType() const throw() { return _errType; }
850  virtual char const * what() const throw() { return _errStr.c_str(); }
851 
852 private:
853  int _errType; // 错误类型(错误号)
854  AnsiString _errStr; // 错误内容字符串
855 };
856 
858 WINUX_FUNC_DECL(bool) ValueIsInArray( StringArray const & arr, String const & val, bool caseInsensitive = false );
859 
861 WINUX_FUNC_DECL(int) Random( int n1, int n2 );
862 
863 
864 // 类型解析功能 -------------------------------------------------------------------------
866 WINUX_FUNC_DECL(bool) ParseBool( AnsiString const & str, bool * boolVal );
868 WINUX_FUNC_DECL(bool) ParseBool( UnicodeString const & str, bool * boolVal );
870 WINUX_FUNC_DECL(bool) ParseInt( AnsiString const & str, int * iVal );
872 WINUX_FUNC_DECL(bool) ParseInt( UnicodeString const & str, int * iVal );
874 WINUX_FUNC_DECL(bool) ParseUInt( AnsiString const & str, uint * uiVal );
876 WINUX_FUNC_DECL(bool) ParseUInt( UnicodeString const & str, uint * uiVal );
878 WINUX_FUNC_DECL(bool) ParseLong( AnsiString const & str, long * lVal );
880 WINUX_FUNC_DECL(bool) ParseLong( UnicodeString const & str, long * lVal );
882 WINUX_FUNC_DECL(bool) ParseULong( AnsiString const & str, ulong * ulVal );
884 WINUX_FUNC_DECL(bool) ParseULong( UnicodeString const & str, ulong * ulVal );
886 WINUX_FUNC_DECL(bool) ParseInt64( AnsiString const & str, int64 * i64Val );
888 WINUX_FUNC_DECL(bool) ParseInt64( UnicodeString const & str, int64 * i64Val );
890 WINUX_FUNC_DECL(bool) ParseUInt64( AnsiString const & str, uint64 * ui64Val );
892 WINUX_FUNC_DECL(bool) ParseUInt64( UnicodeString const & str, uint64 * ui64Val );
894 WINUX_FUNC_DECL(bool) ParseFloat( AnsiString const & str, float * fltVal );
896 WINUX_FUNC_DECL(bool) ParseFloat( UnicodeString const & str, float * fltVal );
898 WINUX_FUNC_DECL(bool) ParseDouble( AnsiString const & str, double * dblVal );
900 WINUX_FUNC_DECL(bool) ParseDouble( UnicodeString const & str, double * dblVal );
901 
902 // -------------------------------------------------------------------------------
903 class GrowBuffer;
904 
907 {
908 public:
909  static void * Alloc( size_t size );
910  static void * Realloc( void * p, size_t newSize );
911  static void Free( void * p );
912 
913 public:
915  Buffer();
916 
920  Buffer( void const * buf, size_t size, bool isPeek = false );
921 
925  template < typename _ChTy >
926  Buffer( XString<_ChTy> const & data, bool isPeek = false )
927  {
928  this->_copyConstruct( data.c_str(), data.size() * sizeof(_ChTy), isPeek );
929  }
930 
932  template < typename _ChTy, typename = CharTypeConstrain<_ChTy> >
933  Buffer( _ChTy const * str, size_t len = npos, bool isPeek = false )
934  {
935  this->_copyConstruct( str, ( len == npos ? StrLen<_ChTy>(str) * sizeof(_ChTy) : len * sizeof(_ChTy) ), isPeek );
936  }
937 
939  virtual ~Buffer();
940 
942  Buffer( Buffer const & other );
943 
945  Buffer & operator = ( Buffer const & other );
946 
947 #ifndef MOVE_SEMANTICS_DISABLED
948 
949  Buffer( Buffer && other );
951  Buffer & operator = ( Buffer && other );
953  Buffer( GrowBuffer && other );
955  Buffer & operator = ( GrowBuffer && other );
956 #endif
957 
964  void setBuf( void const * buf, size_t size, size_t capacity, bool isPeek );
965 
971  void setBuf( void const * buf, size_t size, bool isPeek ) { this->setBuf( buf, size, size, isPeek ); }
972 
974  void alloc( size_t capacity, bool setDataSize = true );
975 
979  void realloc( size_t newCapacity );
980 
984  bool peekCopy( bool copyCapacity = false );
985 
987  void * detachBuf( size_t * size = nullptr );
988 
990  void free();
991 
993  void * getBuf() const { return _buf; }
994 
996  template < typename _Ty >
997  _Ty * getBuf() const { return reinterpret_cast<_Ty *>(_buf); }
998 
1000  void * get() const { return _buf; }
1001 
1003  template < typename _Ty >
1004  _Ty * get() const { return reinterpret_cast<_Ty *>(_buf); }
1005 
1007  winux::byte * getAt( ssize_t i ) const { return reinterpret_cast<winux::byte *>(_buf) + i; }
1008 
1010  template < typename _Ty >
1011  _Ty * getAt( ssize_t i ) const { return reinterpret_cast<_Ty *>(_buf) + i; }
1012 
1014  winux::byte & operator [] ( size_t i ) { return reinterpret_cast<winux::byte *>(_buf)[i]; }
1016  winux::byte const & operator [] ( size_t i ) const { return reinterpret_cast<winux::byte const *>(_buf)[i]; }
1017 
1018  // Iterator 相关
1019  winux::byte * begin() { return reinterpret_cast<winux::byte *>(_buf); }
1020  winux::byte * end() { return reinterpret_cast<winux::byte *>(_buf) + _dataSize; }
1021  winux::byte const * begin() const { return reinterpret_cast<winux::byte *>(_buf); }
1022  winux::byte const * end() const { return reinterpret_cast<winux::byte *>(_buf) + _dataSize; }
1023 
1025  size_t getSize() const { return _dataSize; }
1026 
1028  size_t size() const { return _dataSize; }
1029 
1031  template < typename _Ty >
1032  size_t size() const { return _dataSize / sizeof(_Ty); }
1033 
1035  template < typename _Ty >
1036  size_t count() const { return _dataSize / sizeof(_Ty); }
1037 
1039  void _setSize( size_t dataSize ) { _dataSize = ( dataSize > _capacity ? _capacity : dataSize ); }
1040 
1042  size_t getCapacity() const { return _capacity; }
1043 
1045  size_t capacity() const { return _capacity; }
1046 
1048  bool isPeek() const { return _isPeek; }
1049 
1051  operator bool() const { return _buf != NULL; }
1052 
1054  template < typename _ChTy >
1055  XString<_ChTy> toString() const { return XString<_ChTy>( (_ChTy*)_buf, _dataSize / sizeof(_ChTy) ); }
1056 
1058  AnsiString toAnsi() const { return this->toString<AnsiString::value_type>(); }
1059 
1061  UnicodeString toUnicode() const { return this->toString<UnicodeString::value_type>(); }
1062 
1063  // 比较操作符 --------------------------------------------------------------------------
1064  bool operator == ( Buffer const & other ) const { return MemoryCompare( this->getBuf(), this->getSize(), other.getBuf(), other.getSize() ) == 0; }
1065  bool operator < ( Buffer const & other ) const { return MemoryCompare( this->getBuf(), this->getSize(), other.getBuf(), other.getSize() ) < 0; }
1066  bool operator > ( Buffer const & other ) const { return MemoryCompare( this->getBuf(), this->getSize(), other.getBuf(), other.getSize() ) > 0; }
1067  bool operator != ( Buffer const & other ) const { return !this->operator == (other); }
1068  bool operator >= ( Buffer const & other ) const { return !this->operator < (other); }
1069  bool operator <= ( Buffer const & other ) const { return !this->operator > (other); }
1070 
1071 protected:
1072  // 零初始化
1073  void _zeroInit();
1074  // 拷贝构造(不会判断自身原有资源情况)
1075  void _copyConstruct( void const * buf, size_t size, bool isPeek );
1076 
1077  void * _buf;
1078  size_t _dataSize;
1079  size_t _capacity;
1080  bool _isPeek;
1081 
1082  friend class GrowBuffer;
1083 };
1084 
1086 template < typename _PodType >
1087 class Packet : public Buffer
1088 {
1089 public:
1090  Packet( size_t size = 0 )
1091  {
1092  if ( size > 0 ) this->alloc(size);
1093  }
1094 
1096  _PodType * get() const { return reinterpret_cast<_PodType *>(_buf); }
1097 
1098  _PodType * operator -> () { return reinterpret_cast<_PodType *>(_buf); }
1099  _PodType const * operator -> () const { return reinterpret_cast<_PodType *>(_buf); }
1100 };
1101 
1104 {
1105 public:
1107  explicit GrowBuffer( size_t capacity = 0 );
1108  GrowBuffer( GrowBuffer const & other );
1109  GrowBuffer & operator = ( GrowBuffer const & other );
1110  explicit GrowBuffer( Buffer const & other );
1111  GrowBuffer & operator = ( Buffer const & other );
1112 
1113 #ifndef MOVE_SEMANTICS_DISABLED
1114 
1115  GrowBuffer( GrowBuffer && other );
1117  GrowBuffer & operator = ( GrowBuffer && other );
1119  GrowBuffer( Buffer && other );
1121  GrowBuffer & operator = ( Buffer && other );
1122 #endif
1123 
1128  void append( void const * data, size_t size );
1129 
1131  void append( Buffer const & data ) { this->append( (void const *)data.getBuf(), data.getSize() ); }
1132 
1134  template < typename _ChTy >
1135  void appendString( XString<_ChTy> const & data ) { this->append( (void const *)data.c_str(), data.size() * sizeof(_ChTy) ); }
1136 
1138  template < typename _ChTy, typename = CharTypeConstrain<_ChTy> >
1139  void appendString( _ChTy const * str, size_t len = npos )
1140  {
1141  this->append( (void const *)str, ( len == npos ? StrLen<_ChTy>(str) : len ) * sizeof(_ChTy) );
1142  }
1143 
1145  template < typename _PodType >
1146  void appendType( _PodType const & data, size_t size = sizeof(_PodType) ) { this->append( (void const *)&data, size ); }
1147 
1149  template < typename _PodType, size_t _Count >
1150  void appendType( _PodType const (&data)[_Count] ) { this->append( (void const *)&data, _Count * sizeof(data[0]) ); }
1151 
1153  template < typename _PodType >
1154  void appendType( std::initializer_list<_PodType> list )
1155  {
1156  for ( auto const & e : list )
1157  {
1158  this->appendType<_PodType>( e, sizeof(e) );
1159  }
1160  }
1161 
1163  void erase( size_t start, size_t count = (size_t)-1 );
1164 
1165 protected:
1166  friend class Buffer;
1167 };
1168 
1170 inline static int BufferCompare( Buffer const & buf1, Buffer const & buf2 )
1171 {
1172  return MemoryCompare( buf1.getBuf(), buf1.getSize(), buf2.getBuf(), buf2.getSize() );
1173 }
1174 
1176 inline static int BufferCompareI( Buffer const & buf1, Buffer const & buf2 )
1177 {
1178  return MemoryCompareI( buf1.getBuf(), buf1.getSize(), buf2.getBuf(), buf2.getSize() );
1179 }
1180 
1181 // 混合体相关 ------------------------------------------------------------------------------
1183 class MixedError : public Error
1184 {
1185 public:
1186  enum
1187  {
1194  };
1195 
1196  MixedError( int errType, AnsiString const & errStr ) throw() : Error( errType, errStr ) { }
1197 };
1198 
1200 struct $a
1201 {
1202  std::initializer_list<Mixed> _list;
1203  $a( std::initializer_list<Mixed> && list ) : _list( std::move(list) )
1204  {
1205  }
1206 };
1207 
1209 struct $c
1210 {
1211  std::initializer_list< std::pair< Mixed, Mixed > > _list;
1212  $c( std::initializer_list< std::pair< Mixed, Mixed > > && list ) : _list( std::move(list) )
1213  {
1214  }
1215 };
1216 
1219 {
1220 public:
1221  bool operator () ( Mixed const & v1, Mixed const & v2 ) const;
1222 };
1223 typedef std::map< Mixed, Mixed, MixedLess > MixedMixedMap;
1224 
1227 {
1228 public:
1229  bool operator () ( Mixed const & v1, Mixed const & v2 ) const;
1230 };
1231 typedef std::map< Mixed, Mixed, MixedLessI > MixedMixedMapI;
1232 
1233 typedef std::pair< Mixed const, Mixed > MixedMixedPair;
1234 
1235 
1238 {
1239 public:
1240  explicit Collection( bool caseInsensitive = false );
1241  ~Collection();
1242 
1243  Collection( Collection const & other );
1244  Collection & operator = ( Collection const & other );
1245 
1246  Collection( Collection && other );
1247  Collection & operator = ( Collection && other );
1248 
1250  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1251  explicit Collection( std::map< _KTy, _VTy, _Pr, _Alloc > const & m, bool caseInsensitive = false )
1252  {
1253  this->_zeroInit();
1254  this->assign< _KTy, _VTy, _Pr, _Alloc >( m, caseInsensitive );
1255  }
1256 
1258  template < typename _KTy, typename _VTy, size_t _Count >
1259  explicit Collection( std::pair< _KTy, _VTy > (&pairs)[_Count], bool caseInsensitive = false )
1260  {
1261  this->_zeroInit();
1262  this->assign< _KTy, _VTy, _Count >( pairs, caseInsensitive );
1263  }
1264 
1266  explicit Collection( $c && coll, bool caseInsensitive = false );
1267 
1269  explicit Collection( Mixed const & coll, bool caseInsensitive = false );
1270 
1272  void create( bool caseInsensitive = false );
1273 
1275  void destroy();
1276 
1278  void clear();
1279 
1281  template < typename _Ty, typename _Alloc >
1282  size_t getKeys( std::vector< _Ty, _Alloc > * keys ) const
1283  {
1284  for ( auto it = this->_pKeysArr->begin(); it != this->_pKeysArr->end(); ++it )
1285  keys->push_back(*it);
1286  return keys->size();
1287  }
1288 
1290  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1291  size_t getMap( std::map< _KTy, _VTy, _Pr, _Alloc > * m ) const;
1292 
1294  bool isEmpty() const { return this->getCount() == 0; }
1295 
1297  size_t getCount() const { return this->_pKeysArr != NULL ? this->_pKeysArr->size() : 0; }
1298 
1300  Mixed & operator [] ( Mixed const & k );
1301 
1303  template < typename _ChTy >
1304  Mixed & operator [] ( _ChTy const * k ) { return this->operator [] ( Mixed(k) ); }
1305 
1307  Mixed & at( Mixed const & k );
1309  Mixed const & at( Mixed const & k ) const;
1310 
1312  Mixed const & get( Mixed const & k, Mixed const & defval ) const;
1313 
1315  MixedMixedPair & getPair( size_t i );
1317  MixedMixedPair const & getPair( size_t i ) const;
1318 
1320  void setPair( size_t i, Mixed const & k, Mixed const & v );
1321 
1323  void addPair( Mixed const & k, Mixed const & v );
1324 
1326  void addPair( Mixed const & k, Mixed && v );
1327 
1329  void del( Mixed const & k );
1330 
1332  bool has( Mixed const & k ) const;
1333 
1335  void reverse();
1336 
1337  MixedArray & refKeysArray() { return *this->_pKeysArr; }
1338  MixedArray const & refKeysArray() const { return *this->_pKeysArr; }
1339 
1340  bool getCaseInsensitive() const { return this->_caseInsensitive; }
1341 
1342  MixedMixedMap & refMap() { return *this->_pMap; }
1343  MixedMixedMap const & refMap() const { return *this->_pMap; }
1344 
1345  MixedMixedMapI & refMapI() { return *this->_pMapI; }
1346  MixedMixedMapI const & refMapI() const { return *this->_pMapI; }
1347 
1349  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1350  void assign( std::map< _KTy, _VTy, _Pr, _Alloc > const & m, bool caseInsensitive = false )
1351  {
1352  this->_implAssign(
1353  &Collection::_fxMap<MixedMixedMap, _KTy, _VTy, _Pr, _Alloc>,
1354  &Collection::_fxMap<MixedMixedMapI, _KTy, _VTy, _Pr, _Alloc>,
1355  m,
1356  caseInsensitive
1357  );
1358  }
1359 
1361  template < typename _KTy, typename _VTy, size_t _Count >
1362  void assign( std::pair< _KTy, _VTy > (&pairs)[_Count], bool caseInsensitive = false )
1363  {
1364  this->_implAssign(
1365  &Collection::_fxPairs<MixedMixedMap, _KTy, _VTy, _Count>,
1366  &Collection::_fxPairs<MixedMixedMapI, _KTy, _VTy, _Count>,
1367  pairs,
1368  caseInsensitive
1369  );
1370  }
1371 
1373  void assign( $c && coll, bool caseInsensitive = false )
1374  {
1375  this->_implAssign(
1376  &Collection::_fxC<MixedMixedMap>,
1377  &Collection::_fxC<MixedMixedMapI>,
1378  std::move(coll),
1379  caseInsensitive
1380  );
1381  }
1382 
1383 private:
1384  // 零初始化
1385  void _zeroInit()
1386  {
1387  memset( this, 0, sizeof(*this) );
1388  }
1389  // 拷贝构造(不会判断自身原有资源情况)
1390  void _copyConstruct( Collection const & other );
1391 
1392  // 给数组加入一个唯一键名
1393  bool _addUniqueKey( Mixed const & k );
1394 
1395  template < typename _MAP, typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1396  void _fxMap( _MAP * pMap, std::map< _KTy, _VTy, _Pr, _Alloc > const & m )
1397  {
1398  for ( auto it = m.begin(); it != m.end(); ++it )
1399  {
1400  this->_addUniqueKey(it->first);
1401  (*pMap)[it->first] = it->second;
1402  }
1403  }
1404 
1405  template < typename _MAP, typename _KTy, typename _VTy, size_t _Count >
1406  void _fxPairs( _MAP * pMap, std::pair< _KTy, _VTy > (&pairs)[_Count] )
1407  {
1408  for ( size_t i = 0; i < _Count; ++i )
1409  {
1410  this->_addUniqueKey(pairs[i].first);
1411  (*pMap)[pairs[i].first] = pairs[i].second;
1412  }
1413  }
1414 
1415  template < typename _MAP >
1416  void _fxC( _MAP * pMap, $c && coll );
1417 
1418  template < typename _Fx1, typename _Fx2, typename _Ty >
1419  void _implAssign( _Fx1 fn, _Fx2 fnI, _Ty && m, bool caseInsensitive );
1420 
1421 private:
1422  MixedArray * _pKeysArr;
1423  union
1424  {
1425  MixedMixedMap * _pMap;
1426  MixedMixedMapI * _pMapI;
1427  };
1428  bool _caseInsensitive;
1429 
1430  friend class Mixed;
1431 };
1432 
1433 
1435 WINUX_FUNC_DECL(AnsiString const &) TypeStringA( Mixed const & v );
1437 WINUX_FUNC_DECL(UnicodeString const &) TypeStringW( Mixed const & v );
1438 
1441 {
1442 public:
1443 #ifdef MIXED_REF_NO_EXCEPTION
1444 #define MIXED_REF_TYPE_METHOD( mt, ty, memb, funcname )\
1445  ty& ref##funcname() { return memb; }\
1446  ty const& ref##funcname() const { return memb; }
1447 #define MIXED_REF_TYPE_METHOD_OUTER( mt, ty, memb, funcname )\
1448  template<> inline ty& Mixed::ref<ty>() { return memb; }\
1449  template<> inline ty const& Mixed::ref<ty>() const { return memb; }
1450 #else
1451 #define MIXED_REF_TYPE_METHOD( mt, ty, memb, funcname )\
1452  ty& ref##funcname() { if ( this->_type != mt ) throw MixedError( MixedError::meUnexpectedType, "ref"#funcname"(): " + TypeStringA(*this) + " can not be referenced as a "#mt ); return memb; }\
1453  ty const& ref##funcname() const { if ( this->_type != mt ) throw MixedError( MixedError::meUnexpectedType, "ref"#funcname"(): " + TypeStringA(*this) + " can not be referenced as a "#mt ); return memb; }
1454 #define MIXED_REF_TYPE_METHOD_OUTER( mt, ty, memb, funcname )\
1455  template<> inline ty& Mixed::ref<ty>() { if ( this->_type != mt ) throw MixedError( MixedError::meUnexpectedType, "ref<"#ty">(): " + TypeStringA(*this) + " can not be referenced as a "#mt ); return memb; }\
1456  template<> inline ty const& Mixed::ref<ty>() const { if ( this->_type != mt ) throw MixedError( MixedError::meUnexpectedType, "ref<"#ty">(): " + TypeStringA(*this) + " can not be referenced as a "#mt ); return memb; }
1457 #endif
1458 
1459 #define MIXED_TYPE_ENUM_ITEM( item, nouse1, nouse2, nouse3 ) item,
1460 #define MIXED_TYPE_ENUM_ITEMSTRINGA( item, nouse1, nouse2, nouse3 ) #item,
1461 #define MIXED_TYPE_ENUM_ITEMSTRINGW( item, nouse1, nouse2, nouse3 ) L ## #item,
1462 
1463 #define MIXED_TYPE_LIST(funcmacro) \
1464  funcmacro( MT_BOOLEAN, bool, _boolVal, Bool ) \
1465  funcmacro( MT_CHAR, char, _chVal, Char ) \
1466  funcmacro( MT_BYTE, byte, _btVal, Byte ) \
1467  funcmacro( MT_SHORT, short, _shVal, Short ) \
1468  funcmacro( MT_USHORT, ushort, _ushVal, UShort ) \
1469  funcmacro( MT_INT, int, _iVal, Int ) \
1470  funcmacro( MT_UINT, uint, _uiVal, UInt ) \
1471  funcmacro( MT_LONG, long, _lVal, Long ) \
1472  funcmacro( MT_ULONG, ulong, _ulVal, ULong ) \
1473  funcmacro( MT_INT64, int64, _i64Val, Int64 ) \
1474  funcmacro( MT_UINT64, uint64, _ui64Val, UInt64 ) \
1475  funcmacro( MT_FLOAT, float, _fltVal, Float ) \
1476  funcmacro( MT_DOUBLE, double, _dblVal, Double ) \
1477  funcmacro( MT_ANSI, AnsiString, *_pStr, Ansi ) \
1478  funcmacro( MT_UNICODE, UnicodeString, *_pWStr, Unicode ) \
1479  funcmacro( MT_BINARY, Buffer, *_pBuf, Buffer ) \
1480  funcmacro( MT_ARRAY, MixedArray, *_pArr, Array ) \
1481  funcmacro( MT_COLLECTION, Collection, *_pColl, Collection )
1482 
1484  enum MixedType : uint
1485  {
1486  MT_NULL,
1488  };
1489 
1490  union
1491  {
1492  AnsiString * _pStr;
1493  UnicodeString * _pWStr;
1494  Buffer * _pBuf;
1495  MixedArray * _pArr;
1496  Collection * _pColl;
1498  double _dblVal;
1499  uint64 _ui64Val;
1500  int64 _i64Val;
1501  float _fltVal;
1502  ulong _ulVal;
1503  long _lVal;
1504  uint _uiVal;
1505  int _iVal;
1506  ushort _ushVal;
1507  short _shVal;
1508  byte _btVal;
1509  char _chVal;
1510  bool _boolVal;
1511  };
1512  MixedType _type;
1513 
1514 public:
1515  Mixed();
1516  Mixed( std::nullptr_t );
1517  Mixed( void const * ) = delete;
1518 
1519  // 基本类型构造函数 -------------------------------------------------------------------------
1520  Mixed( bool boolVal );
1521  Mixed( char chVal );
1522  Mixed( byte btVal );
1523  Mixed( short shVal );
1524  Mixed( ushort ushVal );
1525  Mixed( int iVal );
1526  Mixed( uint uiVal );
1527  Mixed( long lVal );
1528  Mixed( ulong ulVal );
1529  Mixed( float fltVal );
1530  Mixed( int64 i64Val );
1531  Mixed( uint64 ui64Val );
1532  Mixed( double dblVal );
1533 
1534  // 字符串构造函数 ---------------------------------------------------------------------------
1535  Mixed( AnsiString const & str );
1536  Mixed( UnicodeString const & str );
1537  Mixed( AnsiString && str );
1538  Mixed( UnicodeString && str );
1539  Mixed( char const * str, size_t len = npos );
1540  Mixed( wchar const * str, size_t len = npos );
1541 
1542  // Buffer构造函数 --------------------------------------------------------------------------
1543  Mixed( Buffer const & buf );
1544  Mixed( void const * binaryData, size_t size, bool isPeek = false );
1545  Mixed( Buffer && buf );
1546  Mixed( GrowBuffer && buf );
1547 
1548  // Array构造函数 ---------------------------------------------------------------------------
1550  Mixed( Mixed * arr, size_t count );
1551 
1553  template < typename _Ty, typename _Alloc >
1554  Mixed( std::vector< _Ty, _Alloc > const & arr )
1555  {
1556  _zeroInit();
1557  this->assign< _Ty, _Alloc >(arr);
1558  }
1559 
1561  template < typename _Ty, size_t _Count >
1562  Mixed( _Ty (&arr)[_Count] )
1563  {
1564  _zeroInit();
1565  this->assign< _Ty, _Count >(arr);
1566  }
1567 
1569  Mixed( std::initializer_list<Mixed> && list );
1570 
1572  Mixed( $a && arr );
1573 
1574  // Collection构造函数 ----------------------------------------------------------------------
1576  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1577  Mixed( std::map< _KTy, _VTy, _Pr, _Alloc > const & m, bool caseInsensitive = false )
1578  {
1579  _zeroInit();
1580  this->assign< _KTy, _VTy, _Pr, _Alloc >( m, caseInsensitive );
1581  }
1582 
1584  template < typename _KTy, typename _VTy, size_t _Count >
1585  Mixed( std::pair< _KTy, _VTy > (&pairs)[_Count], bool caseInsensitive = false )
1586  {
1587  _zeroInit();
1588  this->assign< _KTy, _VTy, _Count >( pairs, caseInsensitive );
1589  }
1590 
1592  Mixed( $c && coll, bool caseInsensitive = false );
1593 
1595  Mixed( Collection const & coll, bool caseInsensitive = false );
1596 
1597  // 拷贝和移动 ------------------------------------------------------------------------------
1599  Mixed( Mixed const & other );
1601  Mixed & operator = ( Mixed const & other );
1602 
1604  Mixed( Mixed && other );
1606  Mixed & operator = ( Mixed && other );
1607 
1609  ~Mixed();
1610 
1612  void free();
1613 
1615  MixedType type() const { return this->_type; }
1616 
1617  // 取得相关类型的引用 --------------------------------------------------------------------
1618  template < typename _ChTy >
1619  XString<_ChTy> & refString();
1620  template < typename _ChTy >
1621  XString<_ChTy> const & refString() const;
1622 
1623  template < typename _Ty >
1624  _Ty & ref();
1625  template < typename _Ty >
1626  _Ty const & ref() const;
1627 
1628  // 生成 Mixed 引用类型方法
1630 
1631  // 类型转换 ----------------------------------------------------------------------------
1632  operator bool() const;
1633  //operator char() const;
1634  operator byte() const;
1635  operator short() const;
1636  operator ushort() const;
1637  operator int() const;
1638  operator uint() const;
1639  operator long() const;
1640  operator ulong() const;
1641  operator float() const;
1642  operator int64() const;
1643  operator uint64() const;
1644  operator double() const;
1645  operator AnsiString() const;
1646  operator UnicodeString() const;
1647  operator Buffer() const;
1648  operator MixedArray() const;
1649  operator Collection() const;
1651  bool toBool() const { return this->operator bool(); }
1652  char toChar() const;// { return this->operator char(); }
1653  byte toByte() const { return this->operator winux::byte(); }
1654  short toShort() const { return this->operator short(); }
1655  ushort toUShort() const { return this->operator winux::ushort(); }
1656  int toInt() const { return this->operator int(); }
1657  uint toUInt() const { return this->operator winux::uint(); }
1658  long toLong() const { return this->operator long(); }
1659  ulong toULong() const { return this->operator winux::ulong(); }
1660  float toFloat() const { return this->operator float(); }
1661  int64 toInt64() const { return this->operator winux::int64(); }
1662  uint64 toUInt64() const { return this->operator winux::uint64(); }
1663  double toDouble() const { return this->operator double(); }
1664  template < typename _ChTy >
1665  XString<_ChTy> toString() const;
1666  AnsiString toAnsi() const { return this->operator AnsiString(); }
1667  UnicodeString toUnicode() const { return this->operator UnicodeString(); }
1668  Buffer toBuffer() const { return this->operator Buffer(); }
1669  MixedArray toArray() const { return this->operator MixedArray(); }
1670  Collection toCollection() const { return this->operator Collection(); }
1671  template < typename _Ty >
1672  _Ty to() const;
1673 
1674  // 比较操作符 --------------------------------------------------------------------------
1675  bool operator == ( Mixed const & other ) const;
1676  bool operator < ( Mixed const & other ) const;
1677  bool operator > ( Mixed const & other ) const;
1678  bool operator != ( Mixed const & other ) const { return !this->operator == (other); }
1679  bool operator >= ( Mixed const & other ) const { return !this->operator < (other); }
1680  bool operator <= ( Mixed const & other ) const { return !this->operator > (other); }
1682  // 判定特殊类型 -------------------------------------------------------------------------
1683  bool isNull() const { return this->_type == MT_NULL; }
1684  bool isNumeric() const { return this->_type > MT_NULL && this->_type < MT_ANSI; }
1685  bool isInteger() const { return this->isNumeric() && this->_type != MT_FLOAT && this->_type != MT_DOUBLE; }
1686  bool isString() const { return this->_type == MT_ANSI || this->_type == MT_UNICODE; }
1687  bool isSequence() const { return this->_type >= MT_ANSI && this->_type <= MT_BINARY; }
1688  bool isAnsi() const { return this->_type == MT_ANSI; }
1689  bool isUnicode() const { return this->_type == MT_UNICODE; }
1690  bool isBinary() const { return this->_type == MT_BINARY; }
1691  bool isContainer() const { return this->_type == MT_ARRAY || this->_type == MT_COLLECTION; }
1692  bool isArray() const { return this->_type == MT_ARRAY; }
1693  bool isCollection() const { return this->_type == MT_COLLECTION; }
1694 
1695  // 创建相关类型 -------------------------------------------------------------------------
1697  template < typename _ChTy >
1698  Mixed & createString();
1700  template < typename _ChTy >
1701  Mixed & createString( XString<_ChTy> const & str );
1703  template < typename _ChTy >
1704  Mixed & createString( XString<_ChTy> && str );
1705 
1707  Mixed & createAnsi( AnsiString const & str );
1709  Mixed & createAnsi( AnsiString && str = Literal<char>::emptyStr );
1711  Mixed & createUnicode( UnicodeString const & str );
1713  Mixed & createUnicode( UnicodeString && str = Literal<wchar>::emptyStr );
1715  Mixed & createBuffer( size_t size = 0 );
1717  Mixed & createArray( size_t count = 0 );
1719  Mixed & createCollection( bool caseInsensitive = false );
1720 
1721  // Buffer有关操作 ----------------------------------------------------------------------
1723  void alloc( size_t size, bool setDataSize = true );
1724 
1728  bool peekCopy( bool copyCapacity = false );
1729 
1733  void * getBuf() const;
1734 
1735  // Array/Collection有关的操作 ----------------------------------------------------------
1739  template < typename _Ty, typename _Alloc >
1740  size_t getArray( std::vector< _Ty, _Alloc > * arr ) const
1741  {
1742  if ( !this->isArray() ) throw MixedError( MixedError::meUnexpectedType, TypeStringA(*this) + " can't support getArray()" );
1743  for ( auto it = this->_pArr->begin(); it != this->_pArr->end(); ++it )
1744  arr->push_back(*it);
1745  return arr->size();
1746  }
1747 
1751  template < typename _KTy, typename _Alloc >
1752  size_t getKeys( std::vector< _KTy, _Alloc > * keys ) const
1753  {
1754  if ( !this->isCollection() ) throw MixedError( MixedError::meUnexpectedType, TypeStringA(*this) + " can't support getKeys()" );
1755  return this->_pColl->getKeys(keys);
1756  }
1757 
1761  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
1762  size_t getMap( std::map< _KTy, _VTy, _Pr, _Alloc > * m ) const
1763  {
1764  if ( !this->isCollection() ) throw MixedError( MixedError::meUnexpectedType, TypeStringA(*this) + " can't support getMap()" );
1765  return this->_pColl->getMap(m);
1766  }
1767 
1771  bool isEmpty() const
1772  {
1773  switch ( this->_type )
1774  {
1775  case MT_ANSI:
1776  return this->_pStr->empty();
1777  case MT_UNICODE:
1778  return this->_pWStr->empty();
1779  case MT_BINARY:
1780  return this->_pBuf->getSize() == 0;
1781  case MT_ARRAY:
1782  return this->_pArr->empty();
1783  case MT_COLLECTION:
1784  return this->_pColl->isEmpty();
1785  default:
1786  return true;
1787  }
1788  }
1789 
1793  size_t getSize() const
1794  {
1795  switch ( this->_type )
1796  {
1797  case MT_ANSI:
1798  return this->_pStr->size();
1799  case MT_UNICODE:
1800  return this->_pWStr->size();
1801  case MT_BINARY:
1802  return this->_pBuf->getSize();
1803  default:
1804  return 0;
1805  }
1806  }
1807 
1811  size_t getCount() const
1812  {
1813  switch ( this->_type )
1814  {
1815  case MT_ARRAY:
1816  return this->_pArr->size();
1817  case MT_COLLECTION:
1818  return this->_pColl->getCount();
1819  default:
1820  return 0;
1821  }
1822  }
1823 
1825  Mixed & operator [] ( Mixed const & k );
1827  Mixed const & operator [] ( Mixed const & k ) const;
1829  template < typename _ChTy >
1830  Mixed & operator [] ( _ChTy const * k ) { return this->operator [] ( Mixed(k) ); }
1832  template < typename _ChTy >
1833  Mixed const & operator [] ( _ChTy const * k ) const { return this->operator [] ( Mixed(k) ); }
1836  template < typename _Ty >
1837  _Ty get( Mixed const & k, Mixed const & defval = mxNull ) const { return this->get( k, defval ).to<_Ty>(); }
1838 
1840  Mixed const & get( Mixed const & k, Mixed const & defval = mxNull ) const;
1841 
1843  MixedMixedPair & getPair( size_t i );
1845  MixedMixedPair const & getPair( size_t i ) const;
1846 
1848  Mixed & setPair( size_t i, Mixed const & k, Mixed const & v );
1849 
1851  {
1852  public:
1853  CollectionAssigner( Mixed * mx ) : _mx(mx) { }
1854  CollectionAssigner & operator()( Mixed const & k, Mixed const & v )
1855  {
1856  if ( _mx->isCollection() ) _mx->_pColl->addPair( k, v );
1857  return *this;
1858  }
1859  CollectionAssigner & operator()( Mixed const & k, Mixed && v )
1860  {
1861  if ( _mx->isCollection() ) _mx->_pColl->addPair( k, std::move(v) );
1862  return *this;
1863  }
1864  operator Mixed & () { return *_mx; }
1865 
1866  private:
1867  Mixed * _mx;
1868  };
1869 
1873  CollectionAssigner addPair( bool caseInsensitive = false )
1874  {
1875  if ( this->_type != MT_COLLECTION ) this->createCollection(caseInsensitive);
1876  return CollectionAssigner(this);
1877  }
1878 
1880  Mixed & addPair( Mixed const & k, Mixed const & v );
1881 
1883  {
1884  public:
1885  ArrayAssigner( Mixed * mx ) : _mx(mx) { }
1886  ArrayAssigner & operator()( Mixed const & v )
1887  {
1888  if ( _mx->isArray() ) _mx->_pArr->push_back(v);
1889  return *this;
1890  }
1891  ArrayAssigner & operator()( Mixed && v )
1892  {
1893  if ( _mx->isArray() ) _mx->_pArr->push_back( std::move(v) );
1894  return *this;
1895  }
1896  operator Mixed & () { return *_mx; }
1897 
1898  private:
1899  Mixed * _mx;
1900  };
1901 
1905  ArrayAssigner add()
1906  {
1907  if ( this->_type != MT_ARRAY ) this->createArray();
1908  return ArrayAssigner(this);
1909  }
1910 
1912  size_t add( Mixed const & v );
1913 
1915  size_t add( Mixed && v );
1916 
1918  size_t addUnique( Mixed const & v );
1919 
1921  size_t addUnique( Mixed && v );
1922 
1924  void del( Mixed const & k );
1925 
1929  bool has( Mixed const & ek ) const;
1930 
1934  Mixed & merge( Mixed const & v );
1935 
1937  Mixed & reverse();
1938 
1939  // 赋值操作 --------------------------------------------------------------------------------
1940  // 基本类型赋值函数 -------------------------------------------------------------------------
1941  void assign( bool boolVal );
1942  void assign( char chVal );
1943  void assign( byte btVal );
1944  void assign( short shVal );
1945  void assign( ushort ushVal );
1946  void assign( int iVal );
1947  void assign( uint uiVal );
1948  void assign( long lVal );
1949  void assign( ulong ulVal );
1950  void assign( float fltVal );
1951  void assign( int64 i64Val );
1952  void assign( uint64 ui64Val );
1953  void assign( double dblVal );
1954 
1955  // 字符串赋值函数 ---------------------------------------------------------------------------
1956  void assign( AnsiString const & str );
1957  void assign( UnicodeString const & str );
1958  void assign( AnsiString && str );
1959  void assign( UnicodeString && str );
1960  void assign( char const * str, size_t len = npos );
1961  void assign( wchar const * str, size_t len = npos );
1962 
1963  // Buffer赋值函数 --------------------------------------------------------------------------
1964  void assign( Buffer const & buf );
1965  void assign( void const * binaryData, size_t size, bool isPeek = false );
1966  void assign( Buffer && buf );
1967  void assign( GrowBuffer && buf );
1968 
1969  // Array赋值函数 ---------------------------------------------------------------------------
1971  template < typename _Ty, typename _Alloc >
1972  void assign( std::vector< _Ty, _Alloc > const & arr )
1973  {
1974  if ( this->_type == MT_ARRAY )
1975  {
1976  this->_pArr->clear();
1977  for ( size_t i = 0; i < arr.size(); ++i )
1978  {
1979  this->_pArr->push_back(arr[i]);
1980  }
1981  }
1982  else
1983  {
1984  this->free();
1985  this->_type = MT_ARRAY;
1986  this->_pArr = new MixedArray( arr.size() );
1987  for ( size_t i = 0; i < arr.size(); ++i )
1988  {
1989  this->_pArr->at(i) = arr[i];
1990  }
1991  }
1992  }
1995  template < typename _Ty, size_t _Count >
1996  void assign( _Ty (&arr)[_Count] )
1997  {
1998  if ( this->_type == MT_ARRAY )
1999  {
2000  this->_pArr->clear();
2001  for ( size_t i = 0; i < _Count; ++i )
2002  {
2003  this->_pArr->push_back(arr[i]);
2004  }
2005  }
2006  else
2007  {
2008  this->free();
2009  this->_type = MT_ARRAY;
2010  this->_pArr = new MixedArray(_Count);
2011  for ( size_t i = 0; i < _Count; ++i )
2012  {
2013  this->_pArr->at(i) = arr[i];
2014  }
2015  }
2016  }
2017 
2019  void assign( Mixed * arr, size_t count );
2020 
2022  void assign( std::initializer_list<Mixed> && list );
2023 
2025  void assign( $a && arr );
2026 
2027  // Collection赋值函数 ----------------------------------------------------------------------
2029  template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
2030  void assign( std::map< _KTy, _VTy, _Pr, _Alloc > const & m, bool caseInsensitive = false )
2031  {
2032  if ( this->_type == MT_COLLECTION )
2033  {
2034  this->_pColl->assign( m, caseInsensitive );
2035  }
2036  else
2037  {
2038  this->free();
2039  this->_type = MT_COLLECTION;
2040  this->_pColl = new Collection( m, caseInsensitive );
2041  }
2042  }
2045  template < typename _KTy, typename _VTy, size_t _Count >
2046  void assign( std::pair< _KTy, _VTy > (&pairs)[_Count], bool caseInsensitive = false )
2047  {
2048  if ( this->_type == MT_COLLECTION )
2049  {
2050  this->_pColl->assign( pairs, caseInsensitive );
2051  }
2052  else
2053  {
2054  this->free();
2055  this->_type = MT_COLLECTION;
2056  this->_pColl = new Collection( pairs, caseInsensitive );
2057  }
2058  }
2059 
2061  void assign( $c && coll, bool caseInsensitive = false );
2062 
2064  void assign( Collection const & coll, bool caseInsensitive = false );
2065 
2066  // JSON相关操作 ----------------------------------------------------------------------------
2067  String myJson( bool autoKeyQuotes = true, String const & spacer = $T(""), String const & newline = $T("") ) const;
2068  String json() const;
2069  Mixed & json( String const & jsonStr );
2070 
2071 private:
2072  // 零初始化
2073  void _zeroInit() { memset( this, 0, sizeof(Mixed) ); }
2074  // 拷贝构造(不会判断自身原有资源情况)
2075  void _copyConstruct( Mixed const & other );
2076  // 拷贝赋值
2077  void _copyAssignment( Mixed const & other );
2078 };
2080 // class Mixed inline functions ---------------------------------------------------------------
2081 template <>
2082 inline XString<char> & Mixed::refString<char>()
2083 {
2084  return this->refAnsi();
2086 
2087 template <>
2088 inline XString<char> const & Mixed::refString<char>() const
2089 {
2090  return this->refAnsi();
2092 
2093 template <>
2094 inline XString<wchar> & Mixed::refString<wchar>()
2095 {
2096  return this->refUnicode();
2098 
2099 template <>
2100 inline XString<wchar> const & Mixed::refString<wchar>() const
2101 {
2102  return this->refUnicode();
2104 
2105 // 生成 Mixed 引用类型模板特化方法
2107 
2108 
2109 template <>
2110 inline XString<char> Mixed::toString<char>() const { return this->toAnsi(); }
2111 
2113 template <>
2114 inline XString<wchar> Mixed::toString<wchar>() const { return this->toUnicode(); }
2115 
2116 template <>
2117 inline Mixed Mixed::to<Mixed>() const { return *this; }
2118 template <>
2119 inline bool Mixed::to<bool>() const { return this->operator bool(); }
2120 template <>
2121 inline char Mixed::to<char>() const { return this->toChar(); }
2122 template <>
2123 inline byte Mixed::to<byte>() const { return this->operator winux::byte(); }
2124 template <>
2125 inline short Mixed::to<short>() const { return this->operator short(); }
2126 template <>
2127 inline ushort Mixed::to<ushort>() const { return this->operator winux::ushort(); }
2128 template <>
2129 inline int Mixed::to<int>() const { return this->operator int(); }
2130 template <>
2131 inline uint Mixed::to<uint>() const { return this->operator winux::uint(); }
2132 template <>
2133 inline long Mixed::to<long>() const { return this->operator long(); }
2134 template <>
2135 inline ulong Mixed::to<ulong>() const { return this->operator winux::ulong(); }
2136 template <>
2137 inline float Mixed::to<float>() const { return this->operator float(); }
2138 template <>
2139 inline int64 Mixed::to<int64>() const { return this->operator winux::int64(); }
2140 template <>
2141 inline uint64 Mixed::to<uint64>() const { return this->operator winux::uint64(); }
2142 template <>
2143 inline double Mixed::to<double>() const { return this->operator double(); }
2144 template <>
2145 inline AnsiString Mixed::to<AnsiString>() const { return this->operator AnsiString(); }
2146 template <>
2147 inline UnicodeString Mixed::to<UnicodeString>() const { return this->operator UnicodeString(); }
2148 template <>
2149 inline Buffer Mixed::to<Buffer>() const { return this->operator Buffer(); }
2150 template <>
2151 inline MixedArray Mixed::to<MixedArray>() const { return this->operator MixedArray(); }
2152 template <>
2153 inline Collection Mixed::to<Collection>() const { return this->operator Collection(); }
2154 
2156 template <>
2157 inline Mixed & Mixed::createString<char>() { return this->createAnsi(); }
2159 template <>
2160 inline Mixed & Mixed::createString<wchar>() { return this->createUnicode(); }
2161 
2163 template <>
2164 inline Mixed & Mixed::createString<char>( XString<char> const & str ) { return this->createAnsi(str); }
2166 template <>
2167 inline Mixed & Mixed::createString<wchar>( XString<wchar> const & str ) { return this->createUnicode(str); }
2168 
2170 template <>
2171 inline Mixed & Mixed::createString<char>( XString<char> && str ) { return this->createAnsi( std::move(str) ); }
2173 template <>
2174 inline Mixed & Mixed::createString<wchar>( XString<wchar> && str ) { return this->createUnicode( std::move(str) ); }
2175 
2176 // class Collection inline functions ------------------------------------------------------
2177 template < typename _KTy, typename _VTy, typename _Pr, typename _Alloc >
2178 inline size_t Collection::getMap( std::map< _KTy, _VTy, _Pr, _Alloc > * m ) const
2179 {
2180  if ( this->_caseInsensitive )
2181  {
2182  for ( auto it = this->_pMapI->begin(); it != this->_pMapI->end(); ++it )
2183  (*m)[(_KTy)it->first] = (_VTy)it->second;
2184  return m->size();
2185  }
2186  else
2187  {
2188  for ( auto it = this->_pMap->begin(); it != this->_pMap->end(); ++it )
2189  (*m)[(_KTy)it->first] = (_VTy)it->second;
2190  return m->size();
2191  }
2192 }
2193 
2194 inline Mixed const & Collection::get( Mixed const & k, Mixed const & defval = mxNull ) const
2195 {
2196  if ( this->_caseInsensitive )
2197  {
2198  if ( this->_pMapI->find(k) != this->_pMapI->end() )
2199  return this->_pMapI->at(k);
2200  }
2201  else
2202  {
2203  if ( this->_pMap->find(k) != this->_pMap->end() )
2204  return this->_pMap->at(k);
2205  }
2206  return defval;
2207 }
2208 
2209 inline bool Collection::has( Mixed const & k ) const
2210 {
2211  return this->_caseInsensitive ? this->_pMapI->find(k) != this->_pMapI->end() : this->_pMap->find(k) != this->_pMap->end();
2212 }
2213 
2214 inline bool Collection::_addUniqueKey( Mixed const & k )
2215 {
2216  if ( this->_caseInsensitive )
2217  {
2218  if ( this->_pMapI->find(k) == this->_pMapI->end() )
2219  {
2220  this->_pKeysArr->push_back(k);
2221  return true;
2222  }
2223  }
2224  else
2225  {
2226  if ( this->_pMap->find(k) == this->_pMap->end() )
2227  {
2228  this->_pKeysArr->push_back(k);
2229  return true;
2230  }
2231  }
2232  return false;
2233 }
2234 
2235 template < typename _MAP >
2236 inline void Collection::_fxC( _MAP * pMap, $c && coll )
2237 {
2238  for ( auto & pr : coll._list )
2239  {
2240  this->_addUniqueKey(pr.first);
2241  (*pMap)[pr.first] = pr.second;
2242  }
2243 }
2244 
2245 template < typename _Fx1, typename _Fx2, typename _Ty >
2246 inline void Collection::_implAssign( _Fx1 fn, _Fx2 fnI, _Ty && m, bool caseInsensitive )
2247 {
2248  if ( this->_pKeysArr && ( this->_pMap || this->_pMapI ) ) // 当前已经存在分配的数组和映射表
2249  {
2250  this->_pKeysArr->clear();
2251 
2252  if ( this->_caseInsensitive )
2253  {
2254  // 当前是大小写无关的,但是目标是大小写相关的,删除当前的创建全新的
2255  if ( !caseInsensitive )
2256  {
2257  this->_caseInsensitive = caseInsensitive;
2258  delete this->_pMapI;
2259  this->_pMapI = NULL;
2260  this->_pMap = new MixedMixedMap();
2261  (this->*fn)( this->_pMap, std::forward<_Ty>(m) );
2262  }
2263  else
2264  {
2265  this->_pMapI->clear();
2266  (this->*fnI)( this->_pMapI, std::forward<_Ty>(m) );
2267  }
2268  }
2269  else
2270  {
2271  // 当前是大小写相关的,但是目标是大小写无关的,删除当前的创建全新的
2272  if ( caseInsensitive )
2273  {
2274  this->_caseInsensitive = caseInsensitive;
2275  delete this->_pMap;
2276  this->_pMap = NULL;
2277  this->_pMapI = new MixedMixedMapI();
2278  (this->*fnI)( this->_pMapI, std::forward<_Ty>(m) );
2279  }
2280  else
2281  {
2282  this->_pMap->clear();
2283  (this->*fn)( this->_pMap, std::forward<_Ty>(m) );
2284  }
2285  }
2286  }
2287  else
2288  {
2289  this->destroy();
2290  this->_caseInsensitive = caseInsensitive;
2291  this->_pKeysArr = new MixedArray(); // 存放keys
2292  if ( this->_caseInsensitive )
2293  {
2294  this->_pMapI = new MixedMixedMapI();
2295  (this->*fnI)( this->_pMapI, std::forward<_Ty>(m) );
2296  }
2297  else
2298  {
2299  this->_pMap = new MixedMixedMap();
2300  (this->*fn)( this->_pMap, std::forward<_Ty>(m) );
2301  }
2302  }
2303 }
2304 
2306 WINUX_FUNC_DECL(std::ostream &) operator << ( std::ostream & o, Mixed const & m );
2307 WINUX_FUNC_DECL(std::wostream &) operator << ( std::wostream & o, Mixed const & m );
2308 
2309 //std::istream & operator >> ( std::istream & o, Mixed const & m );
2310 //std::wistream & operator >> ( std::wistream & o, Mixed const & m );
2311 
2312 } // namespace winux
2313 
2314 #endif // __UTILITIES_HPP__
不能转换到某种类型
Definition: utilities.hpp:1190
XString< char > AnsiString
Definition: utilities.hpp:257
Mixed集合类型的less谓词,大小写无关
Definition: utilities.hpp:1226
XString< char32 > UnicodeString32
Definition: utilities.hpp:260
MixedType
混合体类型识别常量
Definition: utilities.hpp:1484
__int64 int64
Definition: utilities.hpp:232
#define MIXED_TYPE_ENUM_ITEM(item, nouse1, nouse2, nouse3)
Definition: utilities.hpp:1459
$a(std::initializer_list< Mixed > &&list)
Definition: utilities.hpp:1203
static bool IsLittleEndian()
判断编译环境是否为小端序
Definition: utilities.hpp:670
XString< wchar > UnicodeString
Definition: utilities.hpp:258
_TargetCls * get()
Definition: utilities.hpp:587
函数包装,用来将不同调用约定的函数统一包装成默认约定
Definition: utilities.hpp:364
bool ParseLong(AnsiString const &str, long *lVal)
parse long
void * getBuf() const
暴露缓冲区指针
Definition: utilities.hpp:993
$c(std::initializer_list< std::pair< Mixed, Mixed > > &&list)
Definition: utilities.hpp:1212
MapAssigner< _KTy, _VTy, _Pr, _Alloc > Assign(std::map< _KTy, _VTy, _Pr, _Alloc > *m)
给容器赋值
Definition: utilities.hpp:413
intptr_t ssize_t
Definition: utilities.hpp:225
char32_t char32
Definition: utilities.hpp:223
值是Null因此无法操作
Definition: utilities.hpp:1189
Mixed构造集合辅助类
Definition: utilities.hpp:1209
Mixed const mxNull
Mixed(MT_NULL)常量对象
AnsiString toAnsi() const
转换到AnsiString
Definition: utilities.hpp:1058
Array赋值器
Definition: utilities.hpp:394
std::map< String, Mixed > StringMixedMap
Definition: utilities.hpp:278
bool _isPeek
是否为窥视模式
Definition: utilities.hpp:1080
#define MIXED_REF_TYPE_METHOD(mt, ty, memb, funcname)
Definition: utilities.hpp:1451
PlainMembers(PlainMembers &&other)
Definition: utilities.hpp:571
std::map< _KTy, _VTy, _Pr, _Alloc > MapType
Definition: utilities.hpp:378
static int StringCompare(XString< _ChTy > const &str1, XString< _ChTy > const &str2)
字符串比较
Definition: utilities.hpp:691
#define WINUX_DLL
Definition: utilities.hpp:60
wchar_t wchar
Definition: utilities.hpp:229
Collection(std::map< _KTy, _VTy, _Pr, _Alloc > const &m, bool caseInsensitive=false)
构造函数 用map构造Collection
Definition: utilities.hpp:1251
winux::byte const * begin() const
Definition: utilities.hpp:1021
bool isPeek() const
是否为窥探模式
Definition: utilities.hpp:1048
std::initializer_list< std::pair< Mixed, Mixed > > _list
Definition: utilities.hpp:1211
int VoidReturnInt(_Fx fn, _ArgType &&...arg)
调用一个返回void的函数或函数对象,返回一个数字
Definition: utilities.hpp:829
static bool ArrayLess(_Ty const *arr1, size_t count1, _Ty const *arr2, size_t count2)
array less
Definition: utilities.hpp:717
Members(_ArgType &&...arg)
Definition: utilities.hpp:436
bool ParseUInt(AnsiString const &str, uint *uiVal)
parse uint
UnicodeString const & TypeStringW(Mixed const &v)
输出Mixed类型的字符串表示
bool CollectionGreater(Collection const &coll1, Collection const &coll2)
collection greater
typename CharSpec< typename std::decay< _ChTy >::type >::Type CharTypeConstrain
字符类型约束
Definition: utilities.hpp:301
Packet(size_t size=0)
Definition: utilities.hpp:1090
数据包,用来表示一些POD结构体用于网络通信。通常这类结构体实际大小 > sizeof(这类结构体) ...
Definition: utilities.hpp:1087
bool ParseDouble(AnsiString const &str, double *dblVal)
parse double
XStringArray< char16 > UnicodeString16Array
Definition: utilities.hpp:268
MapAssigner(MapType *m)
Definition: utilities.hpp:380
XString< tchar > String
Definition: utilities.hpp:261
std::pair< String, Mixed > StringMixedPair
Definition: utilities.hpp:279
Members(Members &&other)
Definition: utilities.hpp:462
winux::byte * begin()
Definition: utilities.hpp:1019
STL namespace.
XStringArray< char16 > Utf16StringArray
Definition: utilities.hpp:270
bool CollectionLess(Collection const &coll1, Collection const &coll2)
collection less
size_t capacity() const
获取容量大小
Definition: utilities.hpp:1045
size_t _capacity
容量
Definition: utilities.hpp:1079
XString< _ChTy > toString() const
转换到字符串
Definition: utilities.hpp:1055
MixedArray const & refKeysArray() const
Definition: utilities.hpp:1338
bool ValueIsInArray(StringArray const &arr, String const &val, bool caseInsensitive=false)
判断一个字符串值是否在一个字符串数组里,默认大小写敏感
二进制数。编译时计算,0开头(基于8进制)
Definition: utilities.hpp:304
int MemoryCompareI(void const *buf1, size_t n1, void const *buf2, size_t n2)
内存比较(不区分大小写)
std::map< String, String > StringStringMap
Definition: utilities.hpp:274
MixedMixedMap & refMap()
Definition: utilities.hpp:1342
virtual ~Error()
Definition: utilities.hpp:848
winux::byte * end()
Definition: utilities.hpp:1020
static bool ArrayEqual(_Ty const *arr1, size_t count1, _Ty const *arr2, size_t count2)
array equal
Definition: utilities.hpp:757
size_t getSize() const
获取数据大小
Definition: utilities.hpp:1025
void appendType(_PodType const (&data)[_Count])
添加数据:POD类型数组
Definition: utilities.hpp:1150
size_t getCount() const
获取Collection元素个数
Definition: utilities.hpp:1297
std::vector< XString< _ChTy > > XStringArray
Definition: utilities.hpp:264
Buffer(_ChTy const *str, size_t len=npos, bool isPeek=false)
构造函数3 从字符指针创建Buffer,可以指定是否为窥视模式
Definition: utilities.hpp:933
函数特征
Definition: utilities.hpp:8
Mixed构造数组辅助类
Definition: utilities.hpp:1200
std::ostream & operator<<(std::ostream &out, ConsoleAttrT< _VarType > const &tr)
Definition: console.hpp:131
bool ParseInt(AnsiString const &str, int *iVal)
parse int
std::vector< _Ty, _Alloc > VectorType
Definition: utilities.hpp:397
PlainMembers(_ArgType &&...arg)
Definition: utilities.hpp:545
void assign(std::pair< _KTy, _VTy >(&pairs)[_Count], bool caseInsensitive=false)
用pair[]给Collection赋值
Definition: utilities.hpp:1362
bool ParseBool(AnsiString const &str, bool *boolVal)
parse bool
char tchar
Definition: utilities.hpp:245
_Ty * getBuf() const
暴露缓冲区指针
Definition: utilities.hpp:997
size_t usize_t
Definition: utilities.hpp:226
std::map< Mixed, Mixed, MixedLess > MixedMixedMap
Definition: utilities.hpp:1223
bool ParseUInt64(AnsiString const &str, uint64 *ui64Val)
parse uint64
MixedMixedMapI & refMapI()
Definition: utilities.hpp:1345
Members(Members const &other)
Definition: utilities.hpp:446
XString< char32 > Utf32String
Definition: utilities.hpp:260
Collection(std::pair< _KTy, _VTy >(&pairs)[_Count], bool caseInsensitive=false)
构造函数 用pair[]构造Collection
Definition: utilities.hpp:1259
std::pair< Mixed const, Mixed > MixedMixedPair
Definition: utilities.hpp:1233
字符类型规范
Definition: utilities.hpp:293
int Random(int n1, int n2)
随机数,随机产生n1~n2的数字. 包括n1,n2本身
static constexpr size_t const npos
非位置,值为-1。
Definition: utilities.hpp:285
意料外的类型,该类型不能执行这个操作
Definition: utilities.hpp:1191
#define MIXED_TYPE_LIST(funcmacro)
Definition: utilities.hpp:1463
ArrayAssigner(VectorType *a)
Definition: utilities.hpp:399
std::basic_string< _ChTy, std::char_traits< _ChTy >, std::allocator< _ChTy > > XString
Definition: utilities.hpp:255
XStringArray< char > AnsiStringArray
Definition: utilities.hpp:266
std::vector< Mixed > MixedArray
Definition: utilities.hpp:277
size_t getMap(std::map< _KTy, _VTy, _Pr, _Alloc > *m) const
获取映射表,返回键值对个数
Definition: utilities.hpp:2173
缓冲区,表示内存中一块二进制数据(利用malloc/realloc进行内存分配)
Definition: utilities.hpp:906
static bool IsBigEndian()
判断编译环境是否为大端序
Definition: utilities.hpp:677
XStringArray< char > Utf8StringArray
Definition: utilities.hpp:266
void assign(std::map< _KTy, _VTy, _Pr, _Alloc > const &m, bool caseInsensitive=false)
用map给Collection赋值
Definition: utilities.hpp:1350
AnsiString const & TypeStringA(Mixed const &v)
输出Mixed类型的字符串表示
size_t count() const
获取大小
Definition: utilities.hpp:1036
char int8
Definition: utilities.hpp:219
static int BufferCompare(Buffer const &buf1, Buffer const &buf2)
memcmp()
Definition: utilities.hpp:1170
void appendString(_ChTy const *str, size_t len=npos)
添加数据:C串
Definition: utilities.hpp:1139
bool ParseFloat(AnsiString const &str, float *fltVal)
parse float
XString< char > Utf8String
Definition: utilities.hpp:257
bool isset(_MAP const &m, _KEY const &k)
检测map中是否有该键的值
Definition: utilities.hpp:807
MixedMixedMap const & refMap() const
Definition: utilities.hpp:1343
unsigned int uint
Definition: utilities.hpp:215
void _setSize(size_t dataSize)
设置数据大小,不能超过容量大小(不建议外部调用)
Definition: utilities.hpp:1039
XStringArray< char32 > Utf32StringArray
Definition: utilities.hpp:271
__int64 longlong
Definition: utilities.hpp:233
MixedError(int errType, AnsiString const &errStr)
Definition: utilities.hpp:1196
std::map< Mixed, Mixed, MixedLessI > MixedMixedMapI
Definition: utilities.hpp:1231
size_t getKeys(std::vector< _Ty, _Alloc > *keys) const
获取全部键名,返回键名个数
Definition: utilities.hpp:1282
#define WINUX_FUNC_DECL(ret)
Definition: utilities.hpp:64
static void InvertByteOrderArray(_Ty *p, size_t count)
反转字节序。_Ty必须是基本数字类型
Definition: utilities.hpp:658
Tuple参数序列
Definition: utilities.hpp:338
unsigned char byte
Definition: utilities.hpp:249
#define MIXED_REF_TYPE_METHOD_OUTER(mt, ty, memb, funcname)
Definition: utilities.hpp:1454
size_t size() const
获取大小
Definition: utilities.hpp:1032
集合不存在指定键
Definition: utilities.hpp:1193
size_t _dataSize
数据的大小
Definition: utilities.hpp:1078
virtual char const * what() const
Definition: utilities.hpp:850
高效的可增长缓冲区,1.33倍冗余量
Definition: utilities.hpp:1103
bool ParseULong(AnsiString const &str, ulong *ulVal)
parse ulong
Mixed集合类型的less谓词
Definition: utilities.hpp:1218
Mixed const & get(Mixed const &k, Mixed const &defval) const
取得指定&#39;Key&#39;的元素,不存在则返回默认值
Definition: utilities.hpp:2189
void appendType(std::initializer_list< _PodType > list)
添加数据:POD类型std::initializer_list
Definition: utilities.hpp:1154
bool ParseInt64(AnsiString const &str, int64 *i64Val)
parse int64
unsigned __int64 ulonglong
Definition: utilities.hpp:231
bool has(Mixed const &k) const
判断键名是否存在
Definition: utilities.hpp:2204
PlainMembers(PlainMembers const &other)
Definition: utilities.hpp:555
成员隐藏(By pointer)
Definition: utilities.hpp:427
char16_t char16
Definition: utilities.hpp:222
MixedMixedMapI const & refMapI() const
Definition: utilities.hpp:1346
std::vector< _Ty > ToArray(_Ty *arr, uint count)
将C数组转换成vector
Definition: utilities.hpp:814
void append(Buffer const &data)
添加数据:Buffer对象
Definition: utilities.hpp:1131
void setBuf(void const *buf, size_t size, bool isPeek)
设置缓冲区,当isPeek为false时拷贝数据缓冲区
Definition: utilities.hpp:971
UnicodeString toUnicode() const
转换到UnicodeString
Definition: utilities.hpp:1061
int int32
Definition: utilities.hpp:214
XStringArray< wchar > UnicodeStringArray
Definition: utilities.hpp:267
Error(int errType, AnsiString const &errStr)
Definition: utilities.hpp:847
Plain成员隐藏(By plain block)
Definition: utilities.hpp:536
MixedMixedMap * _pMap
映射表
Definition: utilities.hpp:1425
unsigned short ushort
Definition: utilities.hpp:218
XString< char16 > UnicodeString16
Definition: utilities.hpp:259
virtual int getErrType() const
Definition: utilities.hpp:849
void assign($c &&coll, bool caseInsensitive=false)
用$c给Collection赋值
Definition: utilities.hpp:1373
static int BufferCompareI(Buffer const &buf1, Buffer const &buf2)
memicmp()
Definition: utilities.hpp:1176
混合体,能表示多种类型的值
Definition: utilities.hpp:1440
unsigned short uint16
Definition: utilities.hpp:218
size_t getCapacity() const
获取容量大小
Definition: utilities.hpp:1042
Buffer(XString< _ChTy > const &data, bool isPeek=false)
构造函数2 从一个XString创建Buffer,可以指定是否为窥视模式
Definition: utilities.hpp:926
RefParam(ParamTypeRef r)
Definition: utilities.hpp:325
MixedMixedMapI * _pMapI
映射表大小写无关
Definition: utilities.hpp:1426
XStringArray< char32 > UnicodeString32Array
Definition: utilities.hpp:269
int MemoryCompare(void const *buf1, size_t n1, void const *buf2, size_t n2)
内存比较
static FuncTraits< _PfnType >::ReturnType func(_ArgType &&...arg)
Definition: utilities.hpp:367
错误类
Definition: utilities.hpp:838
bool CollectionEqual(Collection const &coll1, Collection const &coll2)
collection equal
static _Ty InvertByteOrder(_Ty v)
反转字节序。_Ty必须是基本数字类型
Definition: utilities.hpp:649
_Ty * getAt(ssize_t i) const
暴露缓冲区指定位置指针
Definition: utilities.hpp:1011
std::initializer_list< Mixed > _list
Definition: utilities.hpp:1202
void * _buf
缓冲区
Definition: utilities.hpp:1077
RefParam< _Ty > Ref(_Ty &r)
向模板参数传递引用型参数
Definition: utilities.hpp:331
unsigned long ulong
Definition: utilities.hpp:216
std::pair< String, String > StringStringPair
Definition: utilities.hpp:275
MixedArray & refKeysArray()
Definition: utilities.hpp:1337
unsigned __int64 uint64
Definition: utilities.hpp:230
unsigned int uint32
Definition: utilities.hpp:215
unsigned char uint8
Definition: utilities.hpp:220
bool isEmpty() const
判断容器是否为空
Definition: utilities.hpp:1294
混合体错误
Definition: utilities.hpp:1183
winux::byte * getAt(ssize_t i) const
暴露缓冲区指定位置指针
Definition: utilities.hpp:1007
static int StringCompareI(XString< _ChTy > const &str1, XString< _ChTy > const &str2)
字符串(大小写无关)比较
Definition: utilities.hpp:704
short int16
Definition: utilities.hpp:217
MAP赋值器
Definition: utilities.hpp:375
XStringArray< tchar > StringArray
Definition: utilities.hpp:272
size_t size() const
获取数据字节大小
Definition: utilities.hpp:1028
static bool ArrayGreater(_Ty const *arr1, size_t count1, _Ty const *arr2, size_t count2)
array greater
Definition: utilities.hpp:737
void appendType(_PodType const &data, size_t size=sizeof(_PodType))
添加数据:POD类型变量
Definition: utilities.hpp:1146
XString< char16 > Utf16String
Definition: utilities.hpp:259
static size_t StrLen(_ChTy const *str)
计算字符串长度
Definition: utilities.hpp:640
void appendString(XString< _ChTy > const &data)
添加数据:XString对象
Definition: utilities.hpp:1135
winux::byte const * end() const
Definition: utilities.hpp:1022
bool getCaseInsensitive() const
Definition: utilities.hpp:1340
跨平台基础功能库
Definition: archives.hpp:7
intptr_t offset_t
Definition: utilities.hpp:225