summaryrefslogtreecommitdiff
path: root/zen/string_traits.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/string_traits.h')
-rwxr-xr-xzen/string_traits.h83
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));
}
}
bgstack15