UDK 3.2.7 C/C++ API Reference
rtl/stringutils.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*
00003  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License or as specified alternatively below. You may obtain a copy of
00008  * the License at http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * Major Contributor(s):
00016  * [ Copyright (C) 2012 Lubos Lunak <l.lunak@suse.cz> (initial developer) ]
00017  *
00018  * All Rights Reserved.
00019  *
00020  * For minor contributions see the git repository.
00021  *
00022  * Alternatively, the contents of this file may be used under the terms of
00023  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
00024  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
00025  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
00026  * instead of those above.
00027  */
00028 
00029 #ifndef _RTL_STRINGUTILS_HXX_
00030 #define _RTL_STRINGUTILS_HXX_
00031 
00032 #include "sal/config.h"
00033 
00034 // The unittest uses slightly different code to help check that the proper
00035 // calls are made. The class is put into a different namespace to make
00036 // sure the compiler generates a different (if generating also non-inline)
00037 // copy of the function and does not merge them together. The class
00038 // is "brought" into the proper rtl namespace by a typedef below.
00039 #ifdef RTL_STRING_UNITTEST
00040 #define rtl rtlunittest
00041 #endif
00042 
00043 namespace rtl
00044 {
00045 
00046 #ifdef RTL_STRING_UNITTEST
00047 #undef rtl
00048 #endif
00049 namespace internal
00050 {
00051 /*
00052 These templates use SFINAE (Substitution failure is not an error) to help distinguish the various
00053 plain C string types: char*, const char*, char[N], const char[N], char[] and const char[].
00054 There are 2 cases:
00055 1) Only string literal (i.e. const char[N]) is wanted, not any of the others.
00056     In this case it is necessary to distinguish between const char[N] and char[N], as the latter
00057     would be automatically converted to the const variant, which is not wanted (not a string literal
00058     with known size of the content). In this case ConstCharArrayDetector is used to ensure the function
00059     is called only with const char[N] arguments. There's no other plain C string type overload.
00060 2) All plain C string types are wanted, and const char[N] needs to be handled differently.
00061     In this case const char[N] would match const char* argument type (not exactly sure why, but it's
00062     consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type
00063     avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer
00064     arguments. The const in the argument is necessary to handle the case when something is explicitly
00065     cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
00066     being const, it would also match const char[N], so another overload with a reference to non-const
00067     and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
00068 Additionally, char[] and const char[] (i.e. size unknown) are rather tricky. Their usage with 'T&' would
00069 mean it would be 'char(&)[]', which seems to be invalid. But gcc and clang somehow manage when it is
00070 a template. while msvc complains about no conversion from char[] to char[1]. And the reference cannot
00071 be avoided, because 'const char[]' as argument type would match also 'const char[N]'
00072 So char[] and const char[] should always be used with their contents specified (which automatically
00073 turns them into char[N] or const char[N]), or char* and const char* should be used.
00074 */
00075 struct Dummy {};
00076 template< typename T1, typename T2 >
00077 struct CharPtrDetector
00078 {
00079 };
00080 template< typename T >
00081 struct CharPtrDetector< const char*, T >
00082 {
00083     typedef T Type;
00084 };
00085 template< typename T >
00086 struct CharPtrDetector< char*, T >
00087 {
00088     typedef T Type;
00089 };
00090 
00091 template< typename T1, typename T2 >
00092 struct NonConstCharArrayDetector
00093 {
00094 };
00095 template< typename T, int N >
00096 struct NonConstCharArrayDetector< char[ N ], T >
00097 {
00098     typedef T Type;
00099 };
00100 #ifdef RTL_STRING_UNITTEST
00101 // never use, until all compilers handle this
00102 template< typename T >
00103 struct NonConstCharArrayDetector< char[], T >
00104 {
00105     typedef T Type;
00106 };
00107 template< typename T >
00108 struct NonConstCharArrayDetector< const char[], T >
00109 {
00110     typedef T Type;
00111 };
00112 #endif
00113 
00114 template< typename T1, typename T2 >
00115 struct ConstCharArrayDetector
00116 {
00117 };
00118 template< int N, typename T >
00119 struct ConstCharArrayDetector< const char[ N ], T >
00120 {
00121     typedef T Type;
00122     static const int size = N;
00123 };
00124 
00125 // this one is used to rule out only const char[N]
00126 template< typename T >
00127 struct ExceptConstCharArrayDetector
00128 {
00129     typedef Dummy Type;
00130 };
00131 template< int N >
00132 struct ExceptConstCharArrayDetector< const char[ N ] >
00133 {
00134 };
00135 // this one is used to rule out only const char[N]
00136 // (const will be brought in by 'const T&' in the function call)
00137 // msvc needs const char[N] here (not sure whether gcc or msvc
00138 // are right, it doesn't matter).
00139 template< typename T >
00140 struct ExceptCharArrayDetector
00141 {
00142     typedef Dummy Type;
00143 };
00144 template< int N >
00145 struct ExceptCharArrayDetector< char[ N ] >
00146 {
00147 };
00148 template< int N >
00149 struct ExceptCharArrayDetector< const char[ N ] >
00150 {
00151 };
00152 
00153 } /* Namespace */
00154 
00155 } /* Namespace */
00156 
00157 #endif /* _RTL_STRINGUTILS_HXX_ */
00158 
00159 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines