From bd6336c629841c6db3a6ca53a936d629d34db53b Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:15:16 +0200 Subject: 4.1 --- zen/string_traits.h | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 zen/string_traits.h (limited to 'zen/string_traits.h') diff --git a/zen/string_traits.h b/zen/string_traits.h new file mode 100644 index 00000000..59da2f79 --- /dev/null +++ b/zen/string_traits.h @@ -0,0 +1,176 @@ +// ************************************************************************** +// * This file is part of the zenXML project. It is distributed under the * +// * Boost Software License, Version 1.0. See accompanying file * +// * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * +// * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** + +#ifndef STRING_TRAITS_HEADER_813274321443234 +#define STRING_TRAITS_HEADER_813274321443234 + +#include "type_tools.h" +#include "assert_static.h" + + +//uniform access to string-like types: classes and character arrays +namespace zen +{ +/* +strBegin(): + std::wstring str(L"dummy"); + char array[] = "dummy"; + const wchar_t* iter = strBegin(str); //returns str.c_str() + const char* iter2 = strBegin(array); //returns array + +strLength(): + strLength(str); //equals str.size() + strLength(array); //equals cStringLength(array) + +StringTraits<>::CharType: + StringTraits::CharType //equals wchar_t + StringTraits ::CharType //equals wchar_t + +StringTraits<>::isStringLike: + StringTraits::isStringLike; //equals "true" + StringTraits ::isStringLike; //equals "false" + +StringTraits<>::isStringClass: + StringTraits::isStringClass //equals "true" + StringTraits ::isStringClass //equals "false" +*/ + + + + + + + + + + + + + +//---------------------- implementation ---------------------- +namespace implementation +{ +template +class HasValueTypedef +{ + typedef char Yes[1]; + typedef char No [2]; + + template class HelperTp {}; + + //detect presence of a member type called value_type + template static Yes& hasMemberValueType(HelperTp*); + template static No& hasMemberValueType(...); + +public: + enum { result = sizeof(hasMemberValueType(NULL)) == sizeof(Yes) + }; +}; + + +template +class HasStringMembers +{ +public: + enum { result = false }; +}; + +template +class HasStringMembers +{ + typedef char Yes[1]; + typedef char No [2]; + + //detect presence of member functions (without specific restriction on return type, within T or one of it's base classes) + template class HelperFn {}; + + struct Fallback + { + int c_str; + int length; + }; + + template + struct Helper2 : public U, public Fallback {}; //U must be a class-type! + + //we don't know the exact declaration of the member attribute (may be in base class), but we know what NOT to expect: + template static No& hasMemberCstr(HelperFn::c_str>*); + template static Yes& hasMemberCstr(...); + + template static No& hasMemberLength(HelperFn::length>*); + template static Yes& hasMemberLength(...); +public: + enum { result = sizeof(hasMemberCstr (NULL)) == sizeof(Yes) && + sizeof(hasMemberLength(NULL)) == sizeof(Yes) + }; +}; + +template struct StringTraits2 { typedef EmptyType Result; }; //"StringTraits2": fix some VS bug with namespace and partial template specialization + +template struct StringTraits2 { typedef typename S::value_type Result; }; +template <> struct StringTraits2 { typedef char Result; }; +template <> struct StringTraits2 { typedef wchar_t Result; }; +} + + +template +struct StringTraits +{ +private: + typedef typename RemoveRef ::Result NonRefType; + typedef typename RemoveConst ::Result NonConstType; + typedef typename RemoveArray ::Result NonArrayType; + typedef typename RemovePointer::Result NonPtrType; + typedef typename RemoveConst ::Result UndecoratedType; //handle "const char* const" +public: + enum + { + isStringClass = implementation::HasStringMembers::result>::result + }; + + typedef typename implementation::StringTraits2::Result CharType; + + enum + { + isStringLike = IsSameType::result || IsSameType::result + }; +}; + + +namespace implementation +{ +template inline +size_t cStringLength(const C* str) //strlen() +{ + assert_static((IsSameType::result || IsSameType::result)); + size_t len = 0; + while (*str++ != 0) + ++len; + return len; +} +} + + +template inline +const typename StringTraits::CharType* strBegin(const S& str, typename S::value_type dummy = 0) { return str.c_str(); } //SFINAE: T must be a "string" + +template +inline const typename StringTraits::CharType* strBegin(const Char* str) { return str; } +inline const char* strBegin(const char& ch) { return &ch; } +inline const wchar_t* strBegin(const wchar_t& ch) { return &ch; } + + +template inline +size_t strLength(const S& str, typename S::value_type dummy = 0) { return str.length(); } //SFINAE: T must be a "string" + +template +inline size_t strLength(const Char* str) { return implementation::cStringLength(str); } +inline size_t strLength(char) { return 1; } +inline size_t strLength(wchar_t) { return 1; } +} + +#endif //STRING_TRAITS_HEADER_813274321443234 -- cgit