diff options
Diffstat (limited to 'zen/string_traits.h')
-rw-r--r-- | zen/string_traits.h | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/zen/string_traits.h b/zen/string_traits.h index 61fa2625..12701dc3 100644 --- a/zen/string_traits.h +++ b/zen/string_traits.h @@ -4,12 +4,13 @@ // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // ************************************************************************** -#ifndef STRING_TRAITS_HEADER_813274321443234 -#define STRING_TRAITS_HEADER_813274321443234 +#ifndef STRING_TRAITS_H_813274321443234 +#define STRING_TRAITS_H_813274321443234 #include <cstring> //strlen #include "type_tools.h" + //uniform access to string-like types, both classes and character arrays namespace zen { @@ -42,12 +43,12 @@ public: StringRef(Iterator first, Iterator last) : len_(last - first), str_(first != last ? &*first : nullptr) {} //StringRef(const Char* str, size_t len) : str_(str), len_(len) {} -> needless constraint! Char* not available for empty range! - const Char* data() const { return str_; } //1. no null-termination! 2. may be nullptr! + Char* data () const { return str_; } //1. no null-termination! 2. may be nullptr! size_t length() const { return len_; } private: - size_t len_; - const Char* str_; + const size_t len_; + Char* str_; }; @@ -67,16 +68,14 @@ namespace implementation template<class S, class Char> //test if result of S::c_str() can convert to const Char* class HasConversion { - typedef char Yes[1]; - typedef char No [2]; + using Yes = char[1]; + using No = char[2]; static Yes& hasConversion(const Char*); static No& hasConversion(...); - static S& createInstance(); - public: - enum { value = sizeof(hasConversion(createInstance().c_str())) == sizeof(Yes) }; + enum { value = sizeof(hasConversion(std::declval<S>().c_str())) == sizeof(Yes) }; }; @@ -89,7 +88,7 @@ struct GetCharTypeImpl<S, true> : typename SelectIf<HasConversion<S, char >::value, char, NullType>::Type >::Type> { - //typedef typename S::value_type Type; + //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*" 2. wxString, wxWidgets v2.9, has some questionable string design: wxString::c_str() returns a proxy (wxCStrData) which @@ -100,8 +99,10 @@ struct GetCharTypeImpl<S, true> : template <> struct GetCharTypeImpl<char, false> : ResultType<char > {}; template <> struct GetCharTypeImpl<wchar_t, false> : ResultType<wchar_t> {}; -template <> struct GetCharTypeImpl<StringRef<char >, false> : ResultType<char > {}; -template <> struct GetCharTypeImpl<StringRef<wchar_t>, false> : ResultType<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> {}; ZEN_INIT_DETECT_MEMBER_TYPE(value_type); @@ -111,11 +112,11 @@ ZEN_INIT_DETECT_MEMBER(length); // template <class S> class StringTraits { - typedef typename RemoveRef <S >::Type NonRefType; - typedef typename RemoveConst <NonRefType >::Type NonConstType; - typedef typename RemoveArray <NonConstType>::Type NonArrayType; - typedef typename RemovePointer<NonArrayType>::Type NonPtrType; - typedef typename RemoveConst <NonPtrType >::Type UndecoratedType; //handle "const char* const" + 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" public: enum @@ -125,7 +126,7 @@ public: HasMember_length <NonConstType>::value }; - typedef typename GetCharTypeImpl<UndecoratedType, isStringClass>::Type CharType; + using CharType = typename GetCharTypeImpl<UndecoratedType, isStringClass>::Type; enum { @@ -171,8 +172,11 @@ inline const char* strBegin(const char* str) { return str; } inline const wchar_t* strBegin(const wchar_t* str) { return str; } inline const char* strBegin(const char& ch) { return &ch; } inline const wchar_t* strBegin(const wchar_t& ch) { return &ch; } -inline const char* strBegin(const StringRef<char >& ref) { return ref.data(); } -inline const wchar_t* strBegin(const StringRef<wchar_t>& ref) { return ref.data(); } + +inline const char* strBegin(const StringRef<char >& ref) { return ref.data(); } +inline const wchar_t* strBegin(const StringRef<wchar_t >& ref) { return ref.data(); } +inline const char* strBegin(const StringRef<const char >& ref) { return ref.data(); } +inline const wchar_t* strBegin(const StringRef<const wchar_t>& ref) { return ref.data(); } template <class S, typename = typename EnableIf<implementation::StringTraits<S>::isStringClass>::Type> inline @@ -185,8 +189,11 @@ inline size_t strLength(const char* str) { return cStringLength(str); } inline size_t strLength(const wchar_t* str) { return cStringLength(str); } inline size_t strLength(char) { return 1; } inline size_t strLength(wchar_t) { return 1; } -inline size_t strLength(const StringRef<char >& ref) { return ref.length(); } -inline size_t strLength(const StringRef<wchar_t>& ref) { return ref.length(); } + +inline size_t strLength(const StringRef<char >& ref) { return ref.length(); } +inline size_t strLength(const StringRef<wchar_t >& ref) { return ref.length(); } +inline size_t strLength(const StringRef<const char >& ref) { return ref.length(); } +inline size_t strLength(const StringRef<const wchar_t>& ref) { return ref.length(); } } @@ -206,4 +213,4 @@ size_t strLength(S&& str) } } -#endif //STRING_TRAITS_HEADER_813274321443234 +#endif //STRING_TRAITS_H_813274321443234 |