diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2018-06-30 12:43:08 +0200 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2018-06-30 12:43:08 +0200 |
commit | a98326eb2954ac1e79f5eac28dbeab3ec15e047f (patch) | |
tree | bb16257a1894b488e365851273735ec13a9442ef /zen/string_traits.h | |
parent | 10.0 (diff) | |
download | FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.tar.gz FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.tar.bz2 FreeFileSync-a98326eb2954ac1e79f5eac28dbeab3ec15e047f.zip |
10.1
Diffstat (limited to 'zen/string_traits.h')
-rwxr-xr-x | zen/string_traits.h | 83 |
1 files changed, 45 insertions, 38 deletions
diff --git a/zen/string_traits.h b/zen/string_traits.h index 805db46d..8187126d 100755 --- a/zen/string_traits.h +++ b/zen/string_traits.h @@ -8,20 +8,20 @@ #define STRING_TRAITS_H_813274321443234 #include <cstring> //strlen -#include "type_tools.h" +#include "type_traits.h" //uniform access to string-like types, both classes and character arrays namespace zen { /* -IsStringLike<>::value: - IsStringLike<const wchar_t*>::value; //equals "true" - IsStringLike<const int*> ::value; //equals "false" +IsStringLikeV<>: + IsStringLikeV<const wchar_t*> //equals "true" + IsStringLikeV<const int*> //equals "false" -GetCharType<>::Type: - GetCharType<std::wstring>::Type //equals wchar_t - GetCharType<wchar_t[5]> ::Type //equals wchar_t +GetCharTypeT<>: + GetCharTypeT<std::wstring> //equals wchar_t + GetCharTypeT<wchar_t[5]> //equals wchar_t strLength(): strLength(str); //equals str.length() @@ -34,6 +34,7 @@ strBegin(): -> not null-terminated! -> may be nullptr if length is 0! strBegin(array); //returns array */ + //reference a sub-string for consumption by zen string_tools template <class Char> class StringRef @@ -79,15 +80,14 @@ public: }; -template <class S, bool isStringClass> struct GetCharTypeImpl : ResultType<NullType> {}; +template <class S, bool isStringClass> struct GetCharTypeImpl { using Type = void; }; template <class S> -struct GetCharTypeImpl<S, true> : - ResultType< - typename SelectIf<HasConversion<S, wchar_t>::value, wchar_t, - typename SelectIf<HasConversion<S, char >::value, char, NullType>::Type - >::Type> +struct GetCharTypeImpl<S, true> { + using Type = std::conditional_t<HasConversion<S, wchar_t>::value, wchar_t, + /**/ std::conditional_t<HasConversion<S, char >::value, char, void>>; + //using Type = typename S::value_type; /*DON'T use S::value_type: 1. support Glib::ustring: value_type is "unsigned int" but c_str() returns "const char*" @@ -96,13 +96,13 @@ struct GetCharTypeImpl<S, true> : */ }; -template <> struct GetCharTypeImpl<char, false> : ResultType<char > {}; -template <> struct GetCharTypeImpl<wchar_t, false> : ResultType<wchar_t> {}; +template <> struct GetCharTypeImpl<char, false> { using Type = char; }; +template <> struct GetCharTypeImpl<wchar_t, false> { using Type = wchar_t; }; -template <> struct GetCharTypeImpl<StringRef<char >, false> : ResultType<char > {}; -template <> struct GetCharTypeImpl<StringRef<wchar_t >, false> : ResultType<wchar_t> {}; -template <> struct GetCharTypeImpl<StringRef<const char >, false> : ResultType<char > {}; -template <> struct GetCharTypeImpl<StringRef<const wchar_t>, false> : ResultType<wchar_t> {}; +template <> struct GetCharTypeImpl<StringRef<char >, false> { using Type = char; }; +template <> struct GetCharTypeImpl<StringRef<wchar_t >, false> { using Type = wchar_t; }; +template <> struct GetCharTypeImpl<StringRef<const char >, false> { using Type = char; }; +template <> struct GetCharTypeImpl<StringRef<const wchar_t>, false> { using Type = wchar_t; }; ZEN_INIT_DETECT_MEMBER_TYPE(value_type); @@ -112,35 +112,42 @@ ZEN_INIT_DETECT_MEMBER(length); // template <class S> class StringTraits { - using NonRefType = typename RemoveRef <S >::Type; - using NonConstType = typename RemoveConst <NonRefType >::Type; - using NonArrayType = typename RemoveArray <NonConstType>::Type; - using NonPtrType = typename RemovePointer<NonArrayType>::Type; - using UndecoratedType = typename RemoveConst <NonPtrType >::Type ; //handle "const char* const" + using CleanType = std::remove_cv_t<std::remove_reference_t<S>>; //std::remove_cvref requires C++20 + using NonArrayType = std::remove_extent_t <CleanType>; + using NonPtrType = std::remove_pointer_t<NonArrayType>; + using UndecoratedType = std::remove_cv_t <NonPtrType>; //handle "const char* const" public: enum { - isStringClass = HasMemberType_value_type<NonConstType>::value && - HasMember_c_str <NonConstType>::value && - HasMember_length <NonConstType>::value + isStringClass = HasMemberType_value_type<CleanType>::value && + HasMember_c_str <CleanType>::value && + HasMember_length <CleanType>::value }; using CharType = typename GetCharTypeImpl<UndecoratedType, isStringClass>::Type; enum { - isStringLike = IsSameType<CharType, char>::value || - IsSameType<CharType, wchar_t>::value + isStringLike = std::is_same_v<CharType, char> || + std::is_same_v<CharType, wchar_t> }; }; } template <class T> -struct IsStringLike : StaticBool<impl::StringTraits<T>::isStringLike> {}; +struct IsStringLike : std::bool_constant<impl::StringTraits<T>::isStringLike> {}; template <class T> -struct GetCharType : ResultType<typename impl::StringTraits<T>::CharType> {}; +struct GetCharType { using Type = typename impl::StringTraits<T>::CharType; }; + + +//template alias helpers: +template<class T> +constexpr bool IsStringLikeV = IsStringLike<T>::value; + +template<class T> +using GetCharTypeT = typename GetCharType<T>::Type; namespace impl @@ -154,7 +161,7 @@ inline size_t cStringLength(const wchar_t* str) { return std::wcslen(str); } template <class C> inline size_t cStringLength(const C* str) { - static_assert(IsSameType<C, char>::value || IsSameType<C, wchar_t>::value, ""); + static_assert(std::is_same_v<C, char> || std::is_same_v<C, wchar_t>); size_t len = 0; while (*str++ != 0) ++len; @@ -162,8 +169,8 @@ size_t cStringLength(const C* str) } #endif -template <class S, typename = typename EnableIf<StringTraits<S>::isStringClass>::Type> inline -const typename GetCharType<S>::Type* strBegin(const S& str) //SFINAE: T must be a "string" +template <class S, typename = std::enable_if_t<StringTraits<S>::isStringClass>> inline +const GetCharTypeT<S>* strBegin(const S& str) //SFINAE: T must be a "string" { return str.c_str(); } @@ -179,7 +186,7 @@ inline const char* strBegin(const StringRef<const char >& ref) { return ref inline const wchar_t* strBegin(const StringRef<const wchar_t>& ref) { return ref.data(); } -template <class S, typename = typename EnableIf<StringTraits<S>::isStringClass>::Type> inline +template <class S, typename = std::enable_if_t<StringTraits<S>::isStringClass>> inline size_t strLength(const S& str) //SFINAE: T must be a "string" { return str.length(); @@ -198,9 +205,9 @@ inline size_t strLength(const StringRef<const wchar_t>& ref) { return ref.length template <class S> inline -auto strBegin(S&& str) -> const typename GetCharType<S>::Type* +auto strBegin(S&& str) -> const GetCharTypeT<S>* { - static_assert(IsStringLike<S>::value, ""); + static_assert(IsStringLikeV<S>); return impl::strBegin(std::forward<S>(str)); } @@ -208,7 +215,7 @@ auto strBegin(S&& str) -> const typename GetCharType<S>::Type* template <class S> inline size_t strLength(S&& str) { - static_assert(IsStringLike<S>::value, ""); + static_assert(IsStringLikeV<S>); return impl::strLength(std::forward<S>(str)); } } |