1281 lines
30 KiB
C++
1281 lines
30 KiB
C++
#pragma once
|
||
|
||
//±ê×¼¿âÀàÐÍÀ©Õ¹²Ù×÷
|
||
//20191212-1029
|
||
|
||
#include <cassert>
|
||
#include <cmath>
|
||
#include <cstdint>
|
||
|
||
#include <type_traits>
|
||
#include <limits>
|
||
#include <algorithm>
|
||
#include <utility>
|
||
#include <tuple>
|
||
#include <functional>
|
||
#include <iterator>
|
||
|
||
#include <string>
|
||
|
||
#include <exception>
|
||
#include <stdexcept>
|
||
#include <random>
|
||
#include <ratio>
|
||
|
||
#include <chrono>
|
||
|
||
|
||
|
||
|
||
//************
|
||
//ÀàÐͱðÃûÀ©Õ¹
|
||
//************
|
||
|
||
|
||
//durationÀ©Õ¹
|
||
namespace std
|
||
{
|
||
namespace chrono
|
||
{
|
||
typedef duration<long, ratio<3600*24>> days;
|
||
typedef duration<long, ratio<3600*24*7>> weeks;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//************
|
||
//»ù´¡ÀàÐÍÀ©Õ¹
|
||
//************
|
||
|
||
//ÎÞÓÃռλÀàÐÍ
|
||
template<int N>
|
||
class BlankType
|
||
{
|
||
};
|
||
|
||
|
||
|
||
//²âÊÔ²ÎÊýÊÇ·ñºÏ·¨Àà
|
||
template<typename ...>
|
||
struct ParamValidTester
|
||
{
|
||
typedef void type;
|
||
};
|
||
|
||
|
||
//ÏÈÈ¥³ýÒýÓÃÔÙÈ¥³ý³£ÊýÒ×±äÊôÐÔ
|
||
template<typename Ty>
|
||
struct RemoveCVRef
|
||
{
|
||
using type = typename std::remove_cv<typename std::remove_reference<Ty>::type>::type;
|
||
};
|
||
|
||
//ºóÕßÈ¥³ýÒýÓó£ÊýÒ×±äºóÊÇ·ñΪǰÕß
|
||
template<typename TyDst, typename TySrc>
|
||
struct IsRemoveCVRefSame:
|
||
std::is_same<TyDst, typename RemoveCVRef<TySrc>::type>
|
||
{
|
||
};
|
||
|
||
|
||
//ºóÕß²ÎÊý°üÊÇ·ñÒª²»Ã»ÓвÎÊý£¬Òª²»Ö»ÓÐÒ»¸ö²¢ÇÒΪǰÕß
|
||
template<typename TyDst, typename ...TySrc_S>
|
||
struct IsNoneOrSame:
|
||
std::integral_constant<bool, sizeof...(TySrc_S)==0>
|
||
{
|
||
};
|
||
template<typename TyDst, typename TySrc>
|
||
struct IsNoneOrSame<TyDst, TySrc>:
|
||
std::is_same<TyDst, TySrc>
|
||
{
|
||
};
|
||
|
||
//ºóÕß²ÎÊý°üÊÇ·ñÒª²»Ã»ÓвÎÊý£¬Òª²»Ö»ÓÐÒ»¸ö²¢ÇÒÈ¥³ýÒýÓó£ÊýÒ×±äºóΪǰÕß
|
||
template<typename TyDst, typename ...TySrc_S>
|
||
struct IsNoneOrRemoveCVRefSame:
|
||
std::integral_constant<bool, sizeof...(TySrc_S)==0>
|
||
{
|
||
};
|
||
template<typename TyDst, typename TySrc>
|
||
struct IsNoneOrRemoveCVRefSame<TyDst, TySrc>:
|
||
IsRemoveCVRefSame<TyDst, TySrc>
|
||
{
|
||
};
|
||
|
||
|
||
//²âÊÔÊÇ·ñΪµü´úÆ÷
|
||
template<class Ty, class= void>
|
||
struct IsIteratorType:
|
||
std::false_type
|
||
{
|
||
};
|
||
template<class Ty>
|
||
struct IsIteratorType<Ty, typename ParamValidTester<
|
||
typename std::iterator_traits<Ty>::iterator_category>::type
|
||
>: std::true_type
|
||
{
|
||
};
|
||
|
||
|
||
//²âÊÔÈ¥³ý³£Ò×±äÒ×ÓÃÊôÐÔºó£¬ÊÇ·ñΪ×Ö·ûÖ¸Õ룬×Ö·ûÊý×é»òstringÀàÐÍ
|
||
template<class Ty>
|
||
struct IsRemoveCVRefSameSzOrString:
|
||
std::integral_constant<bool, IsRemoveCVRefSame<char *, Ty>::value
|
||
|| IsRemoveCVRefSame<const char *, Ty>::value
|
||
|| (std::is_array<typename RemoveCVRef<Ty>::type>::value
|
||
&& IsRemoveCVRefSame<char, typename std::remove_extent<
|
||
typename RemoveCVRef<Ty>::type>::type>::value)
|
||
|| IsRemoveCVRefSame<std::string, Ty>::value>
|
||
{
|
||
};
|
||
|
||
|
||
|
||
//Éú³Éµü´úÆ÷½âÒýÓõÄÀàÐÍ£¬±£Áô³£Ò×±äÒýÓÃÊôÐÔ
|
||
template<typename TyIt>
|
||
struct IteratorDerefType
|
||
{
|
||
using type = decltype(*std::declval<TyIt>());
|
||
};
|
||
|
||
//Éú³Éµü´úÆ÷½âÒýÓõÄÀàÐÍÔÙÈ¥³ý³£Ò×±äÒýÓÃÊôÐÔ
|
||
template<typename TyIt>
|
||
struct IteratorRemoveCVRefDerefType
|
||
{
|
||
using type = typename RemoveCVRef<typename IteratorDerefType<TyIt>::type>::type;
|
||
};
|
||
|
||
|
||
|
||
//¸ù¾ÝÌṩÀ´Ô´ÀàÐ͵ÄÒýÓᢳ£Êý¡¢Ò×±äÊôÐÔ£¬¶ÔÄ¿µÄÀàÐ͸½¼ÓͬÑùµÄÊôÐÔ
|
||
template<typename TySrc, typename TyDst>
|
||
struct TypeAttachAttribute
|
||
{
|
||
using type = TyDst;
|
||
};
|
||
//³£ÊôÐÔÌØ»¯
|
||
template<typename TySrc, typename TyDst>
|
||
struct TypeAttachAttribute<const TySrc, TyDst>
|
||
{
|
||
using type = typename std::add_const<
|
||
typename TypeAttachAttribute<TySrc, TyDst>::type>::type;
|
||
};
|
||
//Ò×±äÊôÐÔÌØ»¯
|
||
template<typename TySrc, typename TyDst>
|
||
struct TypeAttachAttribute<volatile TySrc, TyDst>
|
||
{
|
||
using type = typename std::add_volatile<
|
||
typename TypeAttachAttribute<TySrc, TyDst>::type>::type;
|
||
};
|
||
//×óÖµÒýÓÃÊôÐÔÌØ»¯
|
||
template<typename TySrc, typename TyDst>
|
||
struct TypeAttachAttribute<TySrc &, TyDst>
|
||
{
|
||
using type = typename std::add_lvalue_reference<
|
||
typename TypeAttachAttribute<TySrc, TyDst>::type>::type;
|
||
};
|
||
//ÓÒÖµÒýÓÃÊôÐÔÌØ»¯
|
||
template<typename TySrc, typename TyDst>
|
||
struct TypeAttachAttribute<TySrc &&, TyDst>
|
||
{
|
||
using type = typename std::add_rvalue_reference<
|
||
typename TypeAttachAttribute<TySrc, TyDst>::type>::type;
|
||
};
|
||
|
||
|
||
|
||
//Çóµ÷Ó÷µ»ØÖµÀàÐÍ
|
||
template<typename TyFunc, typename ...Ty_S>
|
||
struct InvokeReturnType
|
||
{
|
||
using type = decltype(std::declval<TyFunc>()(std::declval<Ty_S>()...));
|
||
};
|
||
|
||
|
||
|
||
//ÕûÊýÐòÁÐÄ£°å
|
||
template<size_t ...c_idx_s>
|
||
struct IndexSequence
|
||
{
|
||
};
|
||
template<>
|
||
struct IndexSequence<>
|
||
{
|
||
using value_type = size_t;
|
||
static constexpr size_t size()
|
||
{
|
||
return 0;
|
||
}
|
||
};
|
||
template<int c_idx, int ...c_rest_s>
|
||
struct IndexSequence<c_idx, c_rest_s...>
|
||
{
|
||
using value_type = size_t;
|
||
static constexpr size_t size()
|
||
{
|
||
return IndexSequence<c_rest_s...>::size()+1;
|
||
}
|
||
};
|
||
|
||
//ÕûÊýÄ£°åÌí¼ÓÔªËØº¯Êý
|
||
template<size_t c_new, size_t ...c_idx_s>
|
||
inline IndexSequence<c_idx_s..., c_new> AddIndexSequence(IndexSequence<c_idx_s...>)
|
||
{
|
||
return IndexSequence<c_idx_s..., c_new>();
|
||
}
|
||
|
||
//Éú³É˳ÐòµÝÔöÕûÊýÄ£°å¸¨ÖúÀà
|
||
template<size_t c_size>
|
||
struct _MakeIndexSequenceAssist
|
||
{
|
||
using type = decltype(AddIndexSequence<c_size-1>(
|
||
typename _MakeIndexSequenceAssist<c_size-1>::type()));
|
||
};
|
||
template<>
|
||
struct _MakeIndexSequenceAssist<0>
|
||
{
|
||
using type = IndexSequence<>;
|
||
};
|
||
//Éú³É˳ÐòµÝÔöÕûÊýÄ£°åÀà
|
||
template<size_t c_size>
|
||
using MakeIndexSequence = typename _MakeIndexSequenceAssist<c_size>::type;
|
||
|
||
|
||
|
||
//Ä£°å¶¨³¤ÕûÐÎ
|
||
template<bool c_bSigned, int c_size>
|
||
struct TemplateInt
|
||
{
|
||
};
|
||
template<>
|
||
struct TemplateInt<true, 1>
|
||
{
|
||
using type = int8_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<false, 1>
|
||
{
|
||
using type = uint8_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<true, 2>
|
||
{
|
||
using type = int16_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<false, 2>
|
||
{
|
||
using type = uint16_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<true, 4>
|
||
{
|
||
using type = int32_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<false, 4>
|
||
{
|
||
using type = uint32_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<true, 8>
|
||
{
|
||
using type = int64_t;
|
||
};
|
||
template<>
|
||
struct TemplateInt<false, 8>
|
||
{
|
||
using type = uint64_t;
|
||
};
|
||
|
||
|
||
|
||
//¹ãÒåµÄ±È½Ïº¯ÊýÀà
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
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<arg2;
|
||
}
|
||
};
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
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<arg2 || arg1==arg2;
|
||
}
|
||
};
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
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<arg2 || arg1==arg2);
|
||
}
|
||
};
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
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<arg2);
|
||
}
|
||
};
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
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<typename Ty1, typename Ty2= Ty1>
|
||
using CompareType = std::function<bool(const Ty1 &, const Ty2 &)>;
|
||
|
||
|
||
//±È½ÏÀຯÊýÀ©Õ¹£¬Ê¹ÓÃСÓں͵ÈÓÚº¯Êý
|
||
template<typename Ty1, typename Ty2= Ty1>
|
||
struct ExtendLessEqualWrap
|
||
{
|
||
typedef bool result_type;
|
||
typedef Ty1 first_argument_type;
|
||
typedef Ty2 second_argument_type;
|
||
public:
|
||
CompareType<Ty1, Ty2> funcLT;
|
||
CompareType<Ty1, Ty2> funcEQ;
|
||
public:
|
||
explicit ExtendLessEqualWrap(const CompareType<Ty1, Ty2> &o_funcLT,
|
||
const CompareType<Ty1, Ty2> &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<typename Ty1, typename Ty2= Ty1>
|
||
struct ExtendGreaterWrap
|
||
{
|
||
typedef bool result_type;
|
||
typedef Ty1 first_argument_type;
|
||
typedef Ty2 second_argument_type;
|
||
public:
|
||
CompareType<Ty1, Ty2> funcLT;
|
||
CompareType<Ty1, Ty2> funcEQ;
|
||
public:
|
||
explicit ExtendGreaterWrap(const CompareType<Ty1, Ty2> &o_funcLT,
|
||
const CompareType<Ty1, Ty2> &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<typename Ty1, typename Ty2= Ty1>
|
||
struct ExtendGreaterEqualWrap
|
||
{
|
||
typedef bool result_type;
|
||
typedef Ty1 first_argument_type;
|
||
typedef Ty2 second_argument_type;
|
||
public:
|
||
CompareType<Ty1, Ty2> funcLT;
|
||
CompareType<Ty1, Ty2> funcEQ;
|
||
public:
|
||
explicit ExtendGreaterEqualWrap(const CompareType<Ty1, Ty2> &o_funcLT,
|
||
const CompareType<Ty1, Ty2> &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<typename Ty1, typename Ty2= Ty1>
|
||
struct ExtendNotEqualToWrap
|
||
{
|
||
typedef bool result_type;
|
||
typedef Ty1 first_argument_type;
|
||
typedef Ty2 second_argument_type;
|
||
public:
|
||
CompareType<Ty1, Ty2> funcLT;
|
||
CompareType<Ty1, Ty2> funcEQ;
|
||
public:
|
||
explicit ExtendNotEqualToWrap(const CompareType<Ty1, Ty2> &o_funcLT,
|
||
const CompareType<Ty1, Ty2> &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<typename Ty>
|
||
struct TypeHolder
|
||
{
|
||
Ty hold;
|
||
public:
|
||
//¹¹Ôì
|
||
TypeHolder(const Ty &o_hold):
|
||
hold(o_hold)
|
||
{
|
||
}
|
||
TypeHolder(Ty &&o_hold):
|
||
hold(std::move(o_hold))
|
||
{
|
||
}
|
||
};
|
||
//×óÖµÒýÓÃÌØ»¯
|
||
template<typename Ty>
|
||
struct TypeHolder<Ty &>
|
||
{
|
||
Ty &hold;
|
||
public:
|
||
//¹¹Ôì
|
||
TypeHolder(Ty &o_hold):
|
||
hold(o_hold)
|
||
{
|
||
}
|
||
};
|
||
//ÓÒÖµÒýÓÃÌØ»¯
|
||
template<typename Ty>
|
||
struct TypeHolder<Ty &&>
|
||
{
|
||
Ty &&hold;
|
||
public:
|
||
//¹¹Ôì
|
||
TypeHolder(Ty &&o_hold):
|
||
hold(std::move(o_hold))
|
||
{
|
||
}
|
||
};
|
||
|
||
|
||
|
||
//´æ´¢Ä³ÖµÀàÐÍ£¬²»ÄÜΪÒýÓã¬ÀàÐÍÖ§³Övoid
|
||
template<typename Ty>
|
||
struct ValueHolder
|
||
{
|
||
public:
|
||
using RefType = Ty &;
|
||
using ConstRefType = const Ty &;
|
||
using PtrType = Ty *;
|
||
using ConstPtrType = const Ty *;
|
||
public:
|
||
Ty hold;
|
||
public:
|
||
//Ä£°å¹¹Ôì
|
||
template<typename ...Ty_S>
|
||
explicit ValueHolder(Ty_S &&...args):
|
||
hold(std::forward<Ty_S>(args)...)
|
||
{
|
||
}
|
||
};
|
||
//voidÌØ»¯
|
||
template<>
|
||
struct ValueHolder<void>
|
||
{
|
||
using RefType = void;
|
||
using ConstRefType = void;
|
||
using PtrType = void;
|
||
using ConstPtrType = void;
|
||
};
|
||
|
||
|
||
|
||
//**********************
|
||
//ÀàÐͳÉÔ±»ò¸¨Öúº¯ÊýÀ©Õ¹
|
||
//**********************
|
||
|
||
//µ÷ÓñäÁ¿µÄÎö¹¹º¯Êý
|
||
template<typename Ty>
|
||
inline void CallDestruct(Ty &value)
|
||
{
|
||
value.~Ty();
|
||
}
|
||
|
||
//µ÷ÓñäÁ¿µÄ¹¹Ô캯Êý£¬ÒªÇó±äÁ¿ÒѾÎö¹¹
|
||
template<typename Ty, typename ...Ty_S>
|
||
inline void CallConstruct(Ty &value, Ty_S &&...arg_s)
|
||
{
|
||
new(&value) Ty(std::forward<Ty_S>(arg_s)...);
|
||
}
|
||
|
||
//µ÷ÓñäÁ¿µÄÎö¹¹º¯ÊýºÍ¹¹Ô캯Êý
|
||
template<typename Ty, typename ...Ty_S>
|
||
inline void CallRestruct(Ty &value, Ty_S &&...arg_s)
|
||
{
|
||
CallDestruct(value);
|
||
CallConstruct(value, std::forward<Ty_S>(arg_s)...);
|
||
}
|
||
|
||
|
||
|
||
//ÌáÈ¡±äÁ¿µÄ×óÖµÒýÓÃ
|
||
template<typename Ty>
|
||
inline Ty &GetLref(Ty &&value)
|
||
{
|
||
return value;
|
||
}
|
||
//ÌáÈ¡±äÁ¿µÄ³£×óÖµÒýÓÃ
|
||
template<typename Ty>
|
||
inline const Ty &GetConstLref(Ty &&value)
|
||
{
|
||
return value;
|
||
}
|
||
|
||
|
||
//¶Ô±äÁ¿½øÐÐÖµ¿½±´
|
||
template<typename Ty>
|
||
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<typename Ty>
|
||
inline typename std::enable_if<std::is_array<typename RemoveCVRef<Ty>::type>::value
|
||
&& IsRemoveCVRefSame<char, typename std::remove_extent<
|
||
typename RemoveCVRef<Ty>::type>::type>::value, std::string
|
||
>::type OverrideSzToStr(Ty &&sz)
|
||
{
|
||
return std::string(std::forward<Ty>(sz));
|
||
}
|
||
//c·ç¸ñ×Ö·û´®×ª»¯×Ö·û´®£¬ÆäÓàÇé¿öÖØÔØ
|
||
template<typename Ty>
|
||
inline Ty &&OverrideSzToStr(Ty &&arg)
|
||
{
|
||
return std::forward<Ty>(arg);
|
||
}
|
||
|
||
|
||
|
||
//ÕûÐαȽϸ¨Öúºê
|
||
#define _IS_INT_TYPE(Ty1, Ty2) \
|
||
(std::is_integral<Ty1>::value && std::is_integral<Ty2>::value)
|
||
#define _INT_SIGN_UNSIGN(Ty1, Ty2) \
|
||
((std::is_integral<Ty1>::value && std::is_signed<Ty1>::value)\
|
||
&& std::is_unsigned<Ty2>::value)
|
||
|
||
//ÕûÐÎÀàÐͰ²È«ÅжÏСÓÚ
|
||
template<typename Ty1, typename Ty2>
|
||
inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty1, Ty2), bool
|
||
>::type IntLT(Ty1 num1, Ty2 num2)
|
||
{
|
||
return (num1<0) ? (true)
|
||
: (static_cast<typename std::make_unsigned<Ty1>::type>(num1)<num2);
|
||
}
|
||
template<typename Ty1, typename Ty2>
|
||
inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty2, Ty1), bool
|
||
>::type IntLT(Ty1 num1, Ty2 num2)
|
||
{
|
||
return (num2<0) ? (false)
|
||
: (num1<static_cast<typename std::make_unsigned<Ty2>::type>(num2));
|
||
}
|
||
template<typename Ty1, typename Ty2>
|
||
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<num2;
|
||
}
|
||
|
||
//ÕûÐÎÀàÐͰ²È«ÅжϵÈÓÚ
|
||
template<typename Ty1, typename Ty2>
|
||
inline constexpr typename std::enable_if<_INT_SIGN_UNSIGN(Ty1, Ty2), bool
|
||
>::type IntEQ(Ty1 num1, Ty2 num2)
|
||
{
|
||
return (num1<0) ? (false)
|
||
: (static_cast<typename std::make_unsigned<Ty1>::type>(num1)==num2);
|
||
}
|
||
template<typename Ty1, typename Ty2>
|
||
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<typename std::make_unsigned<Ty2>::type>(num2));
|
||
}
|
||
template<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
inline constexpr typename std::enable_if<_IS_INT_TYPE(Ty1, Ty2), bool
|
||
>::type IntGTE(Ty1 num1, Ty2 num2)
|
||
{
|
||
return !IntLT(num1, num2);
|
||
}
|
||
|
||
//ÕûÐÎÀàÐͰ²È«Åжϲ»µÈÓÚ
|
||
template<typename Ty1, typename Ty2>
|
||
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<Ty1>::value && std::is_floating_point<Ty2>::value)
|
||
#define _FLOAT_COMMON_EPSILON(Ty1, Ty2) \
|
||
(std::max(std::numeric_limits<Ty1>::epsilon(), std::numeric_limits<Ty2>::epsilon()))
|
||
#define _FLOAT_COMMON_MIN(Ty1, Ty2) \
|
||
(std::max(std::numeric_limits<Ty1>::min(), std::numeric_limits<Ty2>::min()))
|
||
#define _FLOAT_ABS(num) ((num)>=0? (num):-(num))
|
||
|
||
//¸¡µãÊý±È½ÏÏàµÈ£¬±£Ö¤Âß¼¹ØÏµ
|
||
template<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<num2 && !FloatEQ(num1, num2, bAbs, ulp);
|
||
}
|
||
|
||
//¸¡µãÊý±È½ÏСÓÚµÈÓÚ£¬±£Ö¤Âß¼¹ØÏµ
|
||
template<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<typename Ty1, typename Ty2>
|
||
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<typename Ty>
|
||
inline typename std::enable_if<std::is_floating_point<Ty>::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<typename Ty>
|
||
inline typename std::enable_if<std::is_floating_point<Ty>::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<typename Ele, typename Ty>
|
||
inline std::string &operator <<(std::basic_string<Ele> &str, Ty &&arg)
|
||
{
|
||
return str += std::forward<Ty>(arg);
|
||
}
|
||
|
||
|
||
|
||
//·¶Î§ÄÚ×ÖµäÐò±È½Ï²Ù×÷£¬Ê¹Óõü´úÆ÷£¬Ð¡ÓÚµÈÓÚ´óÓڷֱ𷵻Ø-1,0,1
|
||
template<typename TyIt1, typename TyIt2,
|
||
typename TyLess= GeneralLess<typename IteratorRemoveCVRefDerefType<TyIt1>::type,
|
||
typename IteratorRemoveCVRefDerefType<TyIt2>::type>,
|
||
typename TyEqual= GeneralEqualTo<typename IteratorRemoveCVRefDerefType<TyIt1>::type,
|
||
typename IteratorRemoveCVRefDerefType<TyIt2>::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<typename Ty>
|
||
struct IsTupleType:
|
||
std::false_type
|
||
{
|
||
};
|
||
template<typename ...Ty_S>
|
||
struct IsTupleType<std::tuple<Ty_S...>>:
|
||
std::true_type
|
||
{
|
||
};
|
||
|
||
|
||
//tupleÀàÐÍת»»À©Õ¹¸¨Öúº¯Êý
|
||
template<typename TyDst, typename TySrc, size_t ...c_idx_s>
|
||
inline TyDst _TupleCastAssist(TySrc &&src, IndexSequence<c_idx_s...>)
|
||
{
|
||
return TyDst(std::get<c_idx_s>(std::forward<TySrc>(src))...);
|
||
}
|
||
//tupleÀàÐÍת»»À©Õ¹£¬Ö±½ÓÍêÃÀת·¢ÒÔÖ§³ÖËùÓеÄÒýÓÃÇé¿ö£¬ÈôÐèÓÒÖµÔò½«tupleÒÔÓÒÖµ´«Èë
|
||
//Ô´ÀàÐÍÐèÒªÄܱ»getº¯Êý²ð½â£¬Ä¿µÄÀàÐÍÐèÒªÄܽÓÊÜÔ´ÀàÐͲð½âºóµÄ¹¹Ô캯Êý
|
||
template<typename TyDst, typename TySrc>
|
||
inline TyDst TupleCast(TySrc &&src)
|
||
{
|
||
return _TupleCastAssist<TyDst>(std::forward<TySrc>(src), MakeIndexSequence<
|
||
std::tuple_size<typename std::remove_reference<TySrc>::type>::value>());
|
||
}
|
||
|
||
|
||
|
||
//tupleÀàÐ͵÷Óú¯Êý·µ»ØÖµÀàÐ͸¨ÖúÀàÐÍ
|
||
template<typename TyFunc, typename TyTup, typename TyIdx>
|
||
struct _TupleInvokeReturnTypeAssist
|
||
{
|
||
};
|
||
template<typename TyFunc, typename TyTup, size_t ...c_idx_s>
|
||
struct _TupleInvokeReturnTypeAssist<TyFunc, TyTup, IndexSequence<c_idx_s...>>
|
||
{
|
||
using type = decltype(std::declval<TyFunc>()(std::get<c_idx_s>(std::declval<TyTup>())...));
|
||
};
|
||
//tupleÀàÐ͵÷Óú¯Êý·µ»ØÖµÀàÐÍ£¬Ê¹ÓôøcvrefµÄÀàÐÍ´«Èë
|
||
template<typename TyFunc, typename TyTup>
|
||
struct TupleInvokeReturnType
|
||
{
|
||
using type = typename _TupleInvokeReturnTypeAssist<TyFunc, TyTup, MakeIndexSequence<
|
||
std::tuple_size<typename std::remove_reference<TyTup>::type>::value>>::type;
|
||
};
|
||
|
||
//tupleÀàÐ͵÷Óú¯Êý¸¨Öúº¯Êý
|
||
template<typename TyFunc, typename TyTup, size_t ...c_idx_s>
|
||
inline typename TupleInvokeReturnType<TyFunc &&, TyTup &&
|
||
>::type _TupleInvokeAssist(TyFunc &&func, TyTup &&tup, IndexSequence<c_idx_s...>)
|
||
{
|
||
return std::forward<TyFunc>(func)(std::get<c_idx_s>(std::forward<TyTup>(tup))...);
|
||
}
|
||
//tupleÀàÐ͵÷Óú¯Êý£¬±¾ÖÊÉÏÖ»ÒªÄܱ»getº¯Êý²ð½â¼´¿É£¬ÈôÐèÓÒÖµÔò½«tupleÒÔÓÒÖµ´«Èë
|
||
template<typename TyFunc, typename TyTup>
|
||
inline typename TupleInvokeReturnType<TyFunc &&, TyTup &&
|
||
>::type TupleInvoke(TyFunc &&func, TyTup &&tup)
|
||
{
|
||
return _TupleInvokeAssist(std::forward<TyFunc>(func), std::forward<TyTup>(tup),
|
||
MakeIndexSequence<std::tuple_size<typename std::remove_reference<TyTup>::type>::value>());
|
||
}
|
||
|
||
|
||
|
||
//hashµ÷Óú¯Êý
|
||
template<typename Ty>
|
||
inline auto HashFunc(Ty &&arg)->
|
||
decltype(std::hash<typename RemoveCVRef<Ty>::type>()(std::forward<Ty>(arg)))
|
||
{
|
||
return std::hash<typename RemoveCVRef<Ty>::type>()(std::forward<Ty>(arg));
|
||
}
|
||
|
||
|
||
//hashµÄÌØÀý»¯
|
||
namespace std
|
||
{
|
||
//¶ÔpairÌØÀý»¯£¬Ã»Óн»»»²»±äÐÔ£¬Óëtuple¼æÈÝ
|
||
template<typename Ty1, typename Ty2>
|
||
struct hash<std::pair<Ty1, Ty2>>
|
||
{
|
||
typedef size_t result_type;
|
||
typedef std::pair<Ty1, Ty2> argument_type;
|
||
result_type operator()(const argument_type &pr) const
|
||
{
|
||
return HashFunc(HashFunc(pr.first))
|
||
^ HashFunc(pr.second);
|
||
}
|
||
};
|
||
|
||
//¶ÔtupleÌØÀý»¯£¬Ã»Óн»»»²»±äÐÔ
|
||
template<typename ...Tys>
|
||
struct hash<std::tuple<Tys...>>
|
||
{
|
||
typedef size_t result_type;
|
||
typedef std::tuple<Tys...> argument_type;
|
||
result_type operator()(const argument_type &tup) const
|
||
{
|
||
return Assist<sizeof...(Tys)>(tup);
|
||
}
|
||
private:
|
||
template<size_t c_index>
|
||
static typename std::enable_if<c_index>=2, result_type
|
||
>::type Assist(const std::tuple<Tys...> &tup)
|
||
{
|
||
return HashFunc(Assist<c_index-1>(tup))
|
||
^ HashFunc(std::get<c_index-1>(tup));
|
||
}
|
||
template<size_t c_index>
|
||
static typename std::enable_if<c_index==1, result_type
|
||
>::type Assist(const std::tuple<Tys...> &tup)
|
||
{
|
||
return HashFunc(std::get<0>(tup));
|
||
}
|
||
template<size_t c_index>
|
||
static typename std::enable_if<c_index==0, result_type
|
||
>::type Assist(const std::tuple<Tys...> &tup)
|
||
{
|
||
return 0;
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
//¸÷Ààµü´úÆ÷hashÀ࣬βºóµü´úÆ÷½âÒýÓò»°²È«
|
||
template<typename Ty>
|
||
struct IteratorHash
|
||
{
|
||
typedef size_t result_type;
|
||
typedef Ty argument_type;
|
||
result_type operator()(argument_type it) const
|
||
{
|
||
return std::hash<decltype(&*it)>()(&*it);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
//¸÷Ààµü´úÆ÷±È½ÏÀ࣬βºóµü´úÆ÷½âÒýÓò»°²È«
|
||
template<typename Ty>
|
||
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<typename Ty>
|
||
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<typename Ty>
|
||
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<typename Ty>
|
||
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);
|
||
}
|
||
|