#pragma once //±ê×¼¿âÀàÐÍÀ©Õ¹²Ù×÷ //20191212-1029 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //************ //ÀàÐͱðÃûÀ©Õ¹ //************ //durationÀ©Õ¹ namespace std { namespace chrono { typedef duration> days; typedef duration> weeks; } } //************ //»ù´¡ÀàÐÍÀ©Õ¹ //************ //ÎÞÓÃռλÀàÐÍ template class BlankType { }; //²âÊÔ²ÎÊýÊÇ·ñºÏ·¨Àà template struct ParamValidTester { typedef void type; }; //ÏÈÈ¥³ýÒýÓÃÔÙÈ¥³ý³£ÊýÒ×±äÊôÐÔ template struct RemoveCVRef { using type = typename std::remove_cv::type>::type; }; //ºóÕßÈ¥³ýÒýÓó£ÊýÒ×±äºóÊÇ·ñΪǰÕß template struct IsRemoveCVRefSame: std::is_same::type> { }; //ºóÕß²ÎÊý°üÊÇ·ñÒª²»Ã»ÓвÎÊý£¬Òª²»Ö»ÓÐÒ»¸ö²¢ÇÒΪǰÕß template struct IsNoneOrSame: std::integral_constant { }; template struct IsNoneOrSame: std::is_same { }; //ºóÕß²ÎÊý°üÊÇ·ñÒª²»Ã»ÓвÎÊý£¬Òª²»Ö»ÓÐÒ»¸ö²¢ÇÒÈ¥³ýÒýÓó£ÊýÒ×±äºóΪǰÕß template struct IsNoneOrRemoveCVRefSame: std::integral_constant { }; template struct IsNoneOrRemoveCVRefSame: IsRemoveCVRefSame { }; //²âÊÔÊÇ·ñΪµü´úÆ÷ template struct IsIteratorType: std::false_type { }; template struct IsIteratorType::iterator_category>::type >: std::true_type { }; //²âÊÔÈ¥³ý³£Ò×±äÒ×ÓÃÊôÐÔºó£¬ÊÇ·ñΪ×Ö·ûÖ¸Õ룬×Ö·ûÊý×é»òstringÀàÐÍ template struct IsRemoveCVRefSameSzOrString: std::integral_constant::value || IsRemoveCVRefSame::value || (std::is_array::type>::value && IsRemoveCVRefSame::type>::type>::value) || IsRemoveCVRefSame::value> { }; //Éú³Éµü´úÆ÷½âÒýÓõÄÀàÐÍ£¬±£Áô³£Ò×±äÒýÓÃÊôÐÔ template struct IteratorDerefType { using type = decltype(*std::declval()); }; //Éú³Éµü´úÆ÷½âÒýÓõÄÀàÐÍÔÙÈ¥³ý³£Ò×±äÒýÓÃÊôÐÔ template struct IteratorRemoveCVRefDerefType { using type = typename RemoveCVRef::type>::type; }; //¸ù¾ÝÌṩÀ´Ô´ÀàÐ͵ÄÒýÓᢳ£Êý¡¢Ò×±äÊôÐÔ£¬¶ÔÄ¿µÄÀàÐ͸½¼ÓͬÑùµÄÊôÐÔ template struct TypeAttachAttribute { using type = TyDst; }; //³£ÊôÐÔÌØ»¯ template struct TypeAttachAttribute { using type = typename std::add_const< typename TypeAttachAttribute::type>::type; }; //Ò×±äÊôÐÔÌØ»¯ template struct TypeAttachAttribute { using type = typename std::add_volatile< typename TypeAttachAttribute::type>::type; }; //×óÖµÒýÓÃÊôÐÔÌØ»¯ template struct TypeAttachAttribute { using type = typename std::add_lvalue_reference< typename TypeAttachAttribute::type>::type; }; //ÓÒÖµÒýÓÃÊôÐÔÌØ»¯ template struct TypeAttachAttribute { using type = typename std::add_rvalue_reference< typename TypeAttachAttribute::type>::type; }; //Çóµ÷Ó÷µ»ØÖµÀàÐÍ template struct InvokeReturnType { using type = decltype(std::declval()(std::declval()...)); }; //ÕûÊýÐòÁÐÄ£°å template struct IndexSequence { }; template<> struct IndexSequence<> { using value_type = size_t; static constexpr size_t size() { return 0; } }; template struct IndexSequence { using value_type = size_t; static constexpr size_t size() { return IndexSequence::size()+1; } }; //ÕûÊýÄ£°åÌí¼ÓÔªËØº¯Êý template inline IndexSequence AddIndexSequence(IndexSequence) { return IndexSequence(); } //Éú³É˳ÐòµÝÔöÕûÊýÄ£°å¸¨ÖúÀà template struct _MakeIndexSequenceAssist { using type = decltype(AddIndexSequence( typename _MakeIndexSequenceAssist::type())); }; template<> struct _MakeIndexSequenceAssist<0> { using type = IndexSequence<>; }; //Éú³É˳ÐòµÝÔöÕûÊýÄ£°åÀà template using MakeIndexSequence = typename _MakeIndexSequenceAssist::type; //Ä£°å¶¨³¤ÕûÐÎ template struct TemplateInt { }; template<> struct TemplateInt { using type = int8_t; }; template<> struct TemplateInt { using type = uint8_t; }; template<> struct TemplateInt { using type = int16_t; }; template<> struct TemplateInt { using type = uint16_t; }; template<> struct TemplateInt { using type = int32_t; }; template<> struct TemplateInt { using type = uint32_t; }; template<> struct TemplateInt { using type = int64_t; }; template<> struct TemplateInt { using type = uint64_t; }; //¹ãÒåµÄ±È½Ïº¯ÊýÀà template struct GeneralLess { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1 struct GeneralEqualTo { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1==arg2; } }; template struct GeneralLessEqual { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1<=arg2; } }; template struct GeneralGreater { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1>arg2; } }; template struct GeneralGreaterEqual { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1>=arg2; } }; template struct GeneralNotEqualTo { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1!=arg2; } }; //À©Õ¹µÄ¹ãÒå±È½Ïº¯ÊýÀ࣬ʹÓÃСÓں͵ÈÓÚ²Ù×÷ÔËËã template struct ExtendGeneralLessEqual { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return arg1 struct ExtendGeneralGreater { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !(arg1 struct ExtendGeneralGreaterEqual { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !(arg1 struct ExtendGeneralNotEqualTo { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !(arg1==arg2); } }; //±È½ÏÀàÐ͵ĺ¯Êý·â×° template using CompareType = std::function; //±È½ÏÀຯÊýÀ©Õ¹£¬Ê¹ÓÃСÓں͵ÈÓÚº¯Êý template struct ExtendLessEqualWrap { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; public: CompareType funcLT; CompareType funcEQ; public: explicit ExtendLessEqualWrap(const CompareType &o_funcLT, const CompareType &o_funcEQ) : funcLT(o_funcLT), funcEQ(o_funcEQ) { } result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return funcLT(arg1, arg2) || funcEQ(arg1, arg2); } }; template struct ExtendGreaterWrap { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; public: CompareType funcLT; CompareType funcEQ; public: explicit ExtendGreaterWrap(const CompareType &o_funcLT, const CompareType &o_funcEQ) : funcLT(o_funcLT), funcEQ(o_funcEQ) { } result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !(funcLT(arg1, arg2) || funcEQ(arg1, arg2)); } }; template struct ExtendGreaterEqualWrap { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; public: CompareType funcLT; CompareType funcEQ; public: explicit ExtendGreaterEqualWrap(const CompareType &o_funcLT, const CompareType &o_funcEQ) : funcLT(o_funcLT), funcEQ(o_funcEQ) { } result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !funcLT(arg1, arg2); } }; template struct ExtendNotEqualToWrap { typedef bool result_type; typedef Ty1 first_argument_type; typedef Ty2 second_argument_type; public: CompareType funcLT; CompareType funcEQ; public: explicit ExtendNotEqualToWrap(const CompareType &o_funcLT, const CompareType &o_funcEQ) : funcLT(o_funcLT), funcEQ(o_funcEQ) { } result_type operator()(const first_argument_type &arg1, const second_argument_type &arg2) const { return !funcEQ(arg1, arg2); } }; //´æ´¢Ä³ÀàÐÍ£¬¿ÉÒÔΪֵ»òÒýÓ㬶Ը÷ÖÖÇé¿öÒѽøÐÐÌØ»¯ //ÖµÀàÐÍÌØ»¯ template struct TypeHolder { Ty hold; public: //¹¹Ôì TypeHolder(const Ty &o_hold): hold(o_hold) { } TypeHolder(Ty &&o_hold): hold(std::move(o_hold)) { } }; //×óÖµÒýÓÃÌØ»¯ template struct TypeHolder { Ty &hold; public: //¹¹Ôì TypeHolder(Ty &o_hold): hold(o_hold) { } }; //ÓÒÖµÒýÓÃÌØ»¯ template struct TypeHolder { Ty &&hold; public: //¹¹Ôì TypeHolder(Ty &&o_hold): hold(std::move(o_hold)) { } }; //´æ´¢Ä³ÖµÀàÐÍ£¬²»ÄÜΪÒýÓã¬ÀàÐÍÖ§³Övoid template struct ValueHolder { public: using RefType = Ty &; using ConstRefType = const Ty &; using PtrType = Ty *; using ConstPtrType = const Ty *; public: Ty hold; public: //Ä£°å¹¹Ôì template explicit ValueHolder(Ty_S &&...args): hold(std::forward(args)...) { } }; //voidÌØ»¯ template<> struct ValueHolder { using RefType = void; using ConstRefType = void; using PtrType = void; using ConstPtrType = void; }; //********************** //ÀàÐͳÉÔ±»ò¸¨Öúº¯ÊýÀ©Õ¹ //********************** //µ÷ÓñäÁ¿µÄÎö¹¹º¯Êý template inline void CallDestruct(Ty &value) { value.~Ty(); } //µ÷ÓñäÁ¿µÄ¹¹Ô캯Êý£¬ÒªÇó±äÁ¿ÒѾ­Îö¹¹ template inline void CallConstruct(Ty &value, Ty_S &&...arg_s) { new(&value) Ty(std::forward(arg_s)...); } //µ÷ÓñäÁ¿µÄÎö¹¹º¯ÊýºÍ¹¹Ô캯Êý template inline void CallRestruct(Ty &value, Ty_S &&...arg_s) { CallDestruct(value); CallConstruct(value, std::forward(arg_s)...); } //ÌáÈ¡±äÁ¿µÄ×óÖµÒýÓà template inline Ty &GetLref(Ty &&value) { return value; } //ÌáÈ¡±äÁ¿µÄ³£×óÖµÒýÓà template inline const Ty &GetConstLref(Ty &&value) { return value; } //¶Ô±äÁ¿½øÐÐÖµ¿½±´ template inline Ty GetValueCopy(const Ty &value) { return Ty(value); } //c·ç¸ñ×Ö·û´®×ª»¯×Ö·û´®£¬×Ö·ûÖ¸ÕëÖØÔØ inline std::string OverrideSzToStr(const char *sz) { return std::string(sz); } inline std::string OverrideSzToStr(char *sz) { return std::string(sz); } //c·ç¸ñ×Ö·û´®×ª»¯×Ö·û´®£¬×Ö·ûÊý×éÖØÔØ template inline typename std::enable_if::type>::value && IsRemoveCVRefSame::type>::type>::value, std::string >::type OverrideSzToStr(Ty &&sz) { return std::string(std::forward(sz)); } //c·ç¸ñ×Ö·û´®×ª»¯×Ö·û´®£¬ÆäÓàÇé¿öÖØÔØ template inline Ty &&OverrideSzToStr(Ty &&arg) { return std::forward(arg); } //ÕûÐαȽϸ¨Öúºê #define _IS_INT_TYPE(Ty1, Ty2) \ (std::is_integral::value && std::is_integral::value) #define _INT_SIGN_UNSIGN(Ty1, Ty2) \ ((std::is_integral::value && std::is_signed::value)\ && std::is_unsigned::value) //ÕûÐÎÀàÐͰ²È«ÅжÏСÓÚ template inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty1, Ty2), bool >::type IntLT(Ty1 num1, Ty2 num2) { return (num1<0) ? (true) : (static_cast::type>(num1) inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty2, Ty1), bool >::type IntLT(Ty1 num1, Ty2 num2) { return (num2<0) ? (false) : (num1::type>(num2)); } template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2) && !_INT_SIGN_UNSIGN(Ty1, Ty2) && !_INT_SIGN_UNSIGN(Ty2, Ty1), bool >::type IntLT(Ty1 num1, Ty2 num2) { return num1 inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty1, Ty2), bool >::type IntEQ(Ty1 num1, Ty2 num2) { return (num1<0) ? (false) : (static_cast::type>(num1)==num2); } template inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty2, Ty1), bool >::type IntEQ(Ty1 num1, Ty2 num2) { return (num2<0) ? (false) : (num1==static_cast::type>(num2)); } template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2) && !_INT_SIGN_UNSIGN(Ty1, Ty2) && !_INT_SIGN_UNSIGN(Ty2, Ty1), bool >::type IntEQ(Ty1 num1, Ty2 num2) { return num1==num2; } //ÕûÐÎÀàÐͰ²È«ÅжÏСÓÚµÈÓÚ template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2), bool >::type IntLTE(Ty1 num1, Ty2 num2) { return IntLT(num1, num2) || IntEQ(num1, num2); } //ÕûÐÎÀàÐͰ²È«ÅжϴóÓÚ template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2), bool >::type IntGT(Ty1 num1, Ty2 num2) { return !(IntLT(num1, num2) || IntEQ(num1, num2)); } //ÕûÐÎÀàÐͰ²È«ÅжϴóÓÚµÈÓÚ template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2), bool >::type IntGTE(Ty1 num1, Ty2 num2) { return !IntLT(num1, num2); } //ÕûÐÎÀàÐͰ²È«Åжϲ»µÈÓÚ template inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2), bool >::type IntNEQ(Ty1 num1, Ty2 num2) { return !IntEQ(num1, num2); } #undef _IS_INT_TYPE #undef _INT_SIGN_UNSIGN //¸¡µãÊý±È½Ï¸¨Öúºê #define _FLOAT_DEFAULT_ULP 10 #define _FLOAT_DEFAULT_ABS_MODE true #define _IS_FLOAT_TYPE(Ty1, Ty2) \ (std::is_floating_point::value && std::is_floating_point::value) #define _FLOAT_COMMON_EPSILON(Ty1, Ty2) \ (std::max(std::numeric_limits::epsilon(), std::numeric_limits::epsilon())) #define _FLOAT_COMMON_MIN(Ty1, Ty2) \ (std::max(std::numeric_limits::min(), std::numeric_limits::min())) #define _FLOAT_ABS(num) ((num)>=0? (num):-(num)) //¸¡µãÊý±È½ÏÏàµÈ£¬±£Ö¤Âß¼­¹ØÏµ template inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatEQ(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return bAbs ? (_FLOAT_ABS(num1-num2)<_FLOAT_COMMON_EPSILON(Ty1, Ty2)*ulp) : (_FLOAT_ABS(num1-num2)<_FLOAT_COMMON_EPSILON(Ty1, Ty2) *(_FLOAT_ABS(num1)+_FLOAT_ABS(num2))*ulp || _FLOAT_ABS(num1-num2)<_FLOAT_COMMON_MIN(Ty1, Ty2)*ulp); } //¸¡µãÊý±È½ÏСÓÚ£¬±£Ö¤Âß¼­¹ØÏµ template inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatLT(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return num1 inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatLTE(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return FloatLT(num1, num2, bAbs, ulp) || FloatEQ(num1, num2, bAbs, ulp); } //¸¡µãÊý±È½Ï´óÓÚ£¬±£Ö¤Âß¼­¹ØÏµ template inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatGT(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return !(FloatLT(num1, num2, bAbs, ulp) || FloatEQ(num1, num2, bAbs, ulp)); } //¸¡µãÊý±È½Ï´óÓÚµÈÓÚ£¬±£Ö¤Âß¼­¹ØÏµ template inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatGTE(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return !FloatLT(num1, num2, bAbs, ulp); } //¸¡µãÊý±È½Ï²»µÈÓÚ£¬±£Ö¤Âß¼­¹ØÏµ template inline constexpr typename std::enable_if<_IS_FLOAT_TYPE(Ty1, Ty2), bool >::type FloatNEQ(Ty1 num1, Ty2 num2, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { return !FloatEQ(num1, num2, bAbs, ulp); } //¸¡µãÊýÏÂת»¯ÕûÊý template inline typename std::enable_if::value, Ty >::type FloatFloor(Ty num, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { Ty res = std::round(num); if(FloatEQ(num, res, bAbs, ulp)) return res; return std::floor(num); } //¸¡µãÊýÉÏת»¯ÕûÊý template inline typename std::enable_if::value, Ty >::type FloatCeil(Ty num, bool bAbs= _FLOAT_DEFAULT_ABS_MODE, int ulp= _FLOAT_DEFAULT_ULP) { Ty res = std::round(num); if(FloatEQ(num, res, bAbs, ulp)) return res; return std::ceil(num); } #undef _FLOAT_DEFAULT_ULP #undef _IS_FLOAT_TYPE #undef _FLOAT_COMMON_EPSILON #undef _FLOAT_COMMON_MIN #undef _FLOAT_ABS //stringµÄÀÛ¼Ó²Ù×÷£¬Ê¹ÓÃ×óÒÆÔËËã·û template inline std::string &operator <<(std::basic_string &str, Ty &&arg) { return str += std::forward(arg); } //·¶Î§ÄÚ×ÖµäÐò±È½Ï²Ù×÷£¬Ê¹Óõü´úÆ÷£¬Ð¡ÓÚµÈÓÚ´óÓڷֱ𷵻Ø-1,0,1 template::type, typename IteratorRemoveCVRefDerefType::type>, typename TyEqual= GeneralEqualTo::type, typename IteratorRemoveCVRefDerefType::type> > inline int SequenceCompare(TyIt1 st1, TyIt1 ed1, TyIt2 st2, TyIt2 ed2, TyLess funcLess= TyLess(), TyEqual funcEqual= TyEqual()) { for(; ; ++st1, ++st2) { //ÅжϽáÊøÌõ¼þ if(st1==ed1) { if(st2==ed2) return 0; else return -1; } else if(st2==ed2) return 1; //ÅжϴóС if(funcLess(*st1, *st2)) return -1; else if(!(funcEqual(*st1, *st2))) return 1; } } //¼ì²éÊÇ·ñΪtupleÀà template struct IsTupleType: std::false_type { }; template struct IsTupleType>: std::true_type { }; //tupleÀàÐÍת»»À©Õ¹¸¨Öúº¯Êý template inline TyDst _TupleCastAssist(TySrc &&src, IndexSequence) { return TyDst(std::get(std::forward(src))...); } //tupleÀàÐÍת»»À©Õ¹£¬Ö±½ÓÍêÃÀת·¢ÒÔÖ§³ÖËùÓеÄÒýÓÃÇé¿ö£¬ÈôÐèÓÒÖµÔò½«tupleÒÔÓÒÖµ´«Èë //Ô´ÀàÐÍÐèÒªÄܱ»getº¯Êý²ð½â£¬Ä¿µÄÀàÐÍÐèÒªÄܽÓÊÜÔ´ÀàÐͲð½âºóµÄ¹¹Ô캯Êý template inline TyDst TupleCast(TySrc &&src) { return _TupleCastAssist(std::forward(src), MakeIndexSequence< std::tuple_size::type>::value>()); } //tupleÀàÐ͵÷Óú¯Êý·µ»ØÖµÀàÐ͸¨ÖúÀàÐÍ template struct _TupleInvokeReturnTypeAssist { }; template struct _TupleInvokeReturnTypeAssist> { using type = decltype(std::declval()(std::get(std::declval())...)); }; //tupleÀàÐ͵÷Óú¯Êý·µ»ØÖµÀàÐÍ£¬Ê¹ÓôøcvrefµÄÀàÐÍ´«Èë template struct TupleInvokeReturnType { using type = typename _TupleInvokeReturnTypeAssist::type>::value>>::type; }; //tupleÀàÐ͵÷Óú¯Êý¸¨Öúº¯Êý template inline typename TupleInvokeReturnType::type _TupleInvokeAssist(TyFunc &&func, TyTup &&tup, IndexSequence) { return std::forward(func)(std::get(std::forward(tup))...); } //tupleÀàÐ͵÷Óú¯Êý£¬±¾ÖÊÉÏÖ»ÒªÄܱ»getº¯Êý²ð½â¼´¿É£¬ÈôÐèÓÒÖµÔò½«tupleÒÔÓÒÖµ´«Èë template inline typename TupleInvokeReturnType::type TupleInvoke(TyFunc &&func, TyTup &&tup) { return _TupleInvokeAssist(std::forward(func), std::forward(tup), MakeIndexSequence::type>::value>()); } //hashµ÷Óú¯Êý template inline auto HashFunc(Ty &&arg)-> decltype(std::hash::type>()(std::forward(arg))) { return std::hash::type>()(std::forward(arg)); } //hashµÄÌØÀý»¯ namespace std { //¶ÔpairÌØÀý»¯£¬Ã»Óн»»»²»±äÐÔ£¬Óëtuple¼æÈÝ template struct hash> { typedef size_t result_type; typedef std::pair argument_type; result_type operator()(const argument_type &pr) const { return HashFunc(HashFunc(pr.first)) ^ HashFunc(pr.second); } }; //¶ÔtupleÌØÀý»¯£¬Ã»Óн»»»²»±äÐÔ template struct hash> { typedef size_t result_type; typedef std::tuple argument_type; result_type operator()(const argument_type &tup) const { return Assist(tup); } private: template static typename std::enable_if=2, result_type >::type Assist(const std::tuple &tup) { return HashFunc(Assist(tup)) ^ HashFunc(std::get(tup)); } template static typename std::enable_if::type Assist(const std::tuple &tup) { return HashFunc(std::get<0>(tup)); } template static typename std::enable_if::type Assist(const std::tuple &tup) { return 0; } }; } //¸÷Ààµü´úÆ÷hashÀ࣬βºóµü´úÆ÷½âÒýÓò»°²È« template struct IteratorHash { typedef size_t result_type; typedef Ty argument_type; result_type operator()(argument_type it) const { return std::hash()(&*it); } }; //¸÷Ààµü´úÆ÷±È½ÏÀ࣬βºóµü´úÆ÷½âÒýÓò»°²È« template struct IteratorLess { typedef bool result_type; typedef Ty first_argument_type; typedef Ty second_argument_type; result_type operator()(const first_argument_type &it1, const second_argument_type &it2) const { return &*it1<&*it2; } }; template struct IteratorEuqalTo { typedef bool result_type; typedef Ty first_argument_type; typedef Ty second_argument_type; result_type operator()(const first_argument_type &it1, const second_argument_type &it2) const { return &*it1==&*it2; } }; //¸÷Ààµü´úÆ÷½âÒýÓÃÖµ±È½ÏÀà template struct IteratorDerefLess { typedef bool result_type; typedef Ty first_argument_type; typedef Ty second_argument_type; result_type operator()(const first_argument_type &it1, const second_argument_type &it2) const { return *it1<*it2; } }; template struct IteratorDerefEuqalTo { typedef bool result_type; typedef Ty first_argument_type; typedef Ty second_argument_type; result_type operator()(const first_argument_type &it1, const second_argument_type &it2) const { return *it1==*it2; } }; //×Ö·ûÊý×ÖÅÐ¶Ï inline constexpr bool IsNumChar(char ch) { return ch>='0' && ch<='9'; } inline constexpr bool IsNotNumChar(char ch) { return !IsNumChar(ch); } //×Ö·û´óд×ÖĸÅÐ¶Ï inline constexpr bool IsUppChar(char ch) { return (ch>='A' && ch<='Z'); } inline constexpr bool IsNotUppChar(char ch) { return !IsUppChar(ch); } //×Ö·û´óд×ÖĸÅÐ¶Ï inline constexpr bool IsLowChar(char ch) { return (ch>='a' && ch<='z'); } inline constexpr bool IsNotLowChar(char ch) { return !IsLowChar(ch); } //×Ö·û×ÖĸÅÐ¶Ï inline constexpr bool IsLetChar(char ch) { return IsUppChar(ch) || IsLowChar(ch); } inline constexpr bool IsNotLetChar(char ch) { return !IsLetChar(ch); } //×Ö·ûÊý×Ö×ÖĸÅÐ¶Ï inline constexpr bool IsNumLetChar(char ch) { return IsNumChar(ch) || IsLetChar(ch); } inline constexpr bool IsNotNumLetChar(char ch) { return !IsNumLetChar(ch); } //×Ö·û±êʶ·ûÅÐ¶Ï inline constexpr bool IsIdChar(char ch) { return IsNumLetChar(ch) || (ch=='_'); } inline constexpr bool IsNotIdChar(char ch) { return !IsIdChar(ch); } //×Ö·ûÊ®Áù½øÖÆÅÐ¶Ï inline constexpr bool IsHexChar(char ch) { return (ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F'); } inline constexpr bool IsNotHexChar(char ch) { return !IsHexChar(ch); } //×Ö·ûasciiÅÐ¶Ï inline constexpr bool IsAsciiChar(char ch) { return ch>=0x00 && ch<=0x7F; } inline constexpr bool IsNotAsciiChar(char ch) { return !IsAsciiChar(ch); } //×Ö·û¹ãÒå±êʶ·ûÅÐ¶Ï inline constexpr bool IsBroadIdChar(char ch) { return IsIdChar(ch) || IsNotAsciiChar(ch); } inline constexpr bool IsNotBroadIdChar(char ch) { return !IsBroadIdChar(ch); } //×Ö·û¿Õ°×·ûÅÐ¶Ï inline constexpr bool IsBlankChar(char ch) { return ch==' ' || ch=='\t' || ch=='\r' || ch=='\n' || ch=='\v' || ch=='\f'; } inline constexpr bool IsNotBlankChar(char ch) { return !IsBlankChar(ch); } //Сд×Öĸת»»´óд×Öĸ inline constexpr char LowCharToUppChar(char ch) { return (char) (IsLowChar(ch) ? 'A'+(ch-'a') : ch); } //´óд×ÖĸתСд×Öĸ inline constexpr char UppCharToLowChar(char ch) { return (char) (IsUppChar(ch) ? 'a'+(ch-'A') : ch); } //Êý×Ö×Ö·ûת»¯Êý×Ö inline constexpr int NumCharToNum(char ch) { return IsNumChar(ch) ? ch-'0' : -1; } //×Öĸ×Ö·ûת»¯Êý×Ö inline constexpr int LetCharToNum(char ch) { return IsLowChar(ch) ? ch-'a' : IsUppChar(ch) ? ch-'A' : -1; } //Ê®Áù½øÖÆ×Ö·ûת»¯Êý×Ö inline constexpr int HexCharToNum(char ch) { return (ch>='0' && ch<='9') ? ch-'0' : (ch>='a' && ch<='f') ? ch-'a'+10 : (ch>='A' && ch<='F') ? ch-'A'+10 : -1; } //Êý×Öת»¯Êý×Ö×Ö·û inline constexpr char NumToNumChar(int i) { return (char) ((i>=0 && i<=9) ? i+'0' : 0); } //Êý×Öת»¯´óд×Öĸ×Ö·û inline constexpr char NumToUppChar(int i) { return (char) ((i>=0 && i<=25) ? i+'A' : 0); } //Êý×Öת»¯Ð¡Ð´×Öĸ×Ö·û inline constexpr char NumToLowChar(int i) { return (char) ((i>=0 && i<=25) ? i+'a' : 0); } //Êý×Öת»¯´óдʮÁù½øÖÆ×Ö·û inline constexpr char NumToUppHexChar(int i) { return (char) ((i>=0 && i<=9) ? i+'0' : (i>=10 && i<=15) ? i+'A' : 0); } //Êý×Öת»¯Ð¡Ð´Ê®Áù½øÖÆ×Ö·û inline constexpr char NumToLowHexChar(int i) { return (char) ((i>=0 && i<=9) ? i+'0' : (i>=10 && i<=15) ? i+'a' : 0); }