diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2012-03-28 21:33:11 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2012-03-28 23:00:53 +0200 |
commit | 81e7364f52b6135776d4999be287524d508a7d08 (patch) | |
tree | 0fd03aa32200b1c8d7e29708aa071b6cf364af4f /sal/inc/rtl/stringutils.hxx | |
parent | 48cd6ac1ec7e92a9c9a21f5365db4f9ff5fde93c (diff) |
move string helper types to stringutils.hxx
Diffstat (limited to 'sal/inc/rtl/stringutils.hxx')
-rw-r--r-- | sal/inc/rtl/stringutils.hxx | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/sal/inc/rtl/stringutils.hxx b/sal/inc/rtl/stringutils.hxx new file mode 100644 index 000000000000..866bf232d37f --- /dev/null +++ b/sal/inc/rtl/stringutils.hxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * [ Copyright (C) 2012 Lubos Lunak <l.lunak@suse.cz> (initial developer) ] + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#ifndef _RTL_STRINGUTILS_HXX_ +#define _RTL_STRINGUTILS_HXX_ + +#include "sal/config.h" + +// The unittest uses slightly different code to help check that the proper +// calls are made. The class is put into a different namespace to make +// sure the compiler generates a different (if generating also non-inline) +// copy of the function and does not merge them together. The class +// is "brought" into the proper rtl namespace by a typedef below. +#ifdef RTL_STRING_UNITTEST +#define rtl rtlunittest +#endif + +namespace rtl +{ + +#ifdef RTL_STRING_UNITTEST +#undef rtl +#endif +namespace internal +{ +/* +These templates use SFINAE (Substitution failure is not an error) to help distinguish the various +plain C string types: char*, const char*, char[N] and const char[N]. There are 2 cases: +1) Only string literal (i.e. const char[N]) is wanted, not any of the others. + In this case it is necessary to distinguish between const char[N] and char[N], as the latter + would be automatically converted to the const variant, which is not wanted (not a string literal + with known size of the content). In this case ConstCharArrayDetector is used to ensure the function + is called only with const char[N] arguments. There's no other plain C string type overload. +2) All plain C string types are wanted, and const char[N] needs to be handled differently. + In this case const char[N] would match const char* argument type (not exactly sure why, but it's + consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type + avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer + arguments. The const in the argument is necessary to handle the case when something is explicitly + cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference + being const, it would also match const char[N], so another overload with a reference to non-const + and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N]. +*/ +struct Dummy {}; +template< typename T1, typename T2 > +struct CharPtrDetector +{ +}; +template< typename T > +struct CharPtrDetector< const char*, T > +{ + typedef T Type; +}; +template< typename T > +struct CharPtrDetector< char*, T > +{ + typedef T Type; +}; + +template< typename T1, typename T2 > +struct NonConstCharArrayDetector +{ +}; +template< typename T, int N > +struct NonConstCharArrayDetector< char[ N ], T > +{ + typedef T Type; +}; + +template< typename T1, typename T2 > +struct ConstCharArrayDetector +{ +}; +template< int N, typename T > +struct ConstCharArrayDetector< const char[ N ], T > +{ + typedef T Type; + static const int size = N; +}; +} + +} /* Namespace */ + +#endif /* _RTL_STRINGUTILS_HXX_ */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |