1 #ifndef CORELIB___NCBISTL__HPP
2 #define CORELIB___NCBISTL__HPP
3 
4 /*  $Id: ncbistl.hpp 602172 2020-02-18 15:13:29Z ucko $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author:  Denis Vakatov
30  *
31  *
32  */
33 
34 /// @file ncbistl.hpp
35 /// The NCBI C++/STL use hints.
36 
37 
38 #include <common/ncbi_export.h>
39 #include <iosfwd>
40 #include <type_traits>
41 #include <typeinfo>
42 
43 
44 // Get rid of some warnings in MSVC++
45 #if (_MSC_VER >= 1200)
46 // too long identificator name in the debug info;  truncated
47 #  pragma warning(disable: 4786)
48 // too long decorated name;  truncated
49 #  pragma warning(disable: 4503)
50 // default copy constructor cannot be generated
51 #  pragma warning(disable: 4511)
52 // default assignment operator cannot be generated
53 #  pragma warning(disable: 4512)
54 // synonymous name used
55 #  pragma warning(disable: 4097)
56 // inherits ... via dominance
57 #  pragma warning(disable: 4250)
58 // 'this' : used in base member initializer list
59 #  pragma warning(disable: 4355)
60 // identifier was truncated to '255' characters in the browser information
61 #  pragma warning(disable: 4786)
62 #endif /* _MSC_VER >= 1200 */
63 
64 
65 /** @addtogroup STL
66  *
67  * @{
68  */
69 
70 
71 /// Define a new scope.
72 #define BEGIN_SCOPE(ns) namespace ns {
73 
74 /// End the previously defined scope.
75 #define END_SCOPE(ns) }
76 
77 /// Use the specified namespace.
78 #define USING_SCOPE(ns) using namespace ns
79 
80 // Using STD and NCBI namespaces
81 
82 /// Define the std namespace.
83 #define NCBI_NS_STD  std
84 
85 /// Use the std namespace.
86 #define NCBI_USING_NAMESPACE_STD using namespace NCBI_NS_STD
87 
88 /// Define the name for the NCBI namespace.
89 #define NCBI_NS_NCBI ncbi
90 
91 /// Place it for adding new funtionality to STD scope
92 #define BEGIN_STD_SCOPE BEGIN_SCOPE(NCBI_NS_STD)
93 
94 /// End previously defined STD scope.
95 #define END_STD_SCOPE   END_SCOPE(NCBI_NS_STD)
96 
97 /// Define ncbi namespace.
98 ///
99 /// Place at beginning of file for NCBI related code.
100 #define BEGIN_NCBI_SCOPE BEGIN_SCOPE(NCBI_NS_NCBI)
101 
102 /// End previously defined NCBI scope.
103 #define END_NCBI_SCOPE   END_SCOPE(NCBI_NS_NCBI)
104 
105 /// For using NCBI namespace code.
106 #define USING_NCBI_SCOPE USING_SCOPE(NCBI_NS_NCBI)
107 
108 
109 /// Magic spell ;-) needed for some weird compilers... very empiric.
110 namespace NCBI_NS_STD  { /* the fake one */ }
111 
112 /// Magic spell ;-) needed for some weird compilers... very empiric.
113 namespace NCBI_NS_NCBI { /* the fake one, +"std" */ NCBI_USING_NAMESPACE_STD; }
114 
115 /// Magic spell ;-) needed for some weird compilers... very empiric.
116 namespace NCBI_NS_NCBI { /* the fake one */ }
117 
118 
119 #if !defined(NCBI_NAME2)
120 /// Name concatenation macro with two names.
121 /// NB: If this names are macros themselves expanding will not take place.
122 #  define NCBI_NAME2(Name1, Name2) Name1##Name2
123 #endif
124 #if !defined(NCBI_NAME3)
125 /// Name concatenation macro with three names.
126 /// NB: If this names are macros themselves expanding will not take place.
127 #  define NCBI_NAME3(Name1, Name2, Name3) Name1##Name2##Name3
128 #endif
129 
130 #if !defined(NCBI_EAT_SEMICOLON)
131 namespace DummyNS { class CDummyClassToEatSemicolon; }
132 #  define NCBI_EAT_SEMICOLON(UniqueName)                \
133     using ::DummyNS::CDummyClassToEatSemicolon
134 #endif
135 
136 #define BEGIN_NAMESPACE(ns) namespace ns { NCBI_EAT_SEMICOLON(ns)
137 #define END_NAMESPACE(ns) } NCBI_EAT_SEMICOLON(ns)
138 #define BEGIN_NCBI_NAMESPACE BEGIN_NAMESPACE(NCBI_NS_NCBI)
139 #define END_NCBI_NAMESPACE END_NAMESPACE(NCBI_NS_NCBI)
140 #define BEGIN_STD_NAMESPACE BEGIN_NAMESPACE(NCBI_NS_STD)
141 #define END_STD_NAMESPACE END_NAMESPACE(NCBI_NS_STD)
142 #define BEGIN_LOCAL_NAMESPACE namespace { NCBI_EAT_SEMICOLON(ns)
143 #define END_LOCAL_NAMESPACE } NCBI_EAT_SEMICOLON(ns)
144 
145 /// Convert some value to string even if this value is macro itself
146 #define NCBI_AS_STRING(value)   NCBI_AS_STRING2(value)
147 #define NCBI_AS_STRING2(value)   #value
148 
149 
150 #if defined(NCBI_COMPILER_MSVC) && _MSC_VER < 1400 && !defined(for)
151 /// Fix nonstandard 'for' statement behaviour on MSVC 7.1.
152 # define for if(0);else for
153 #endif
154 
155 #ifdef NCBI_COMPILER_ICC
156 /// ICC may fail to generate code preceded by "template<>".
157 #define EMPTY_TEMPLATE
158 #else
159 #define EMPTY_TEMPLATE template<>
160 #endif
161 
162 #ifdef NCBI_COMPILER_WORKSHOP
163 # if NCBI_COMPILER_VERSION < 530
164 /// Advance iterator to end and then break out of loop.
165 ///
166 /// Sun WorkShop < 5.3 fails to call destructors for objects created in
167 /// for-loop initializers; this macro prevents trouble with iterators
168 /// that contain CRefs by advancing them to the end, avoiding
169 /// "deletion of referenced CObject" errors.
170 #  define BREAK(it) while (it) { ++(it); }  break
171 # else
172 #  define BREAK(it) break
173 # endif
174 #else
175 # define BREAK(it) break
176 #endif
177 
178 #if defined(NCBI_COMPILER_GCC) || defined(NCBI_COMPILER_WORKSHOP)
179 #  ifdef NCBI_COMPILER_GCC
180 #    include <algorithm>
181 #  endif
182 // This template is used by some stl algorithms (sort, reverse...)
183 // We need to have our own implementation because some C++ Compiler vendors
184 // implemented it by using a temporary variable and an assignment operator
185 // instead of std::swap function.
186 // GCC 3.4 note: because this compiler has a broken function template
187 // specialization this template function should be defined before
188 // including any stl include files.
189 BEGIN_STD_SCOPE
190 template<typename Iter>
191 inline
iter_swap(Iter it1,Iter it2)192 void iter_swap( Iter it1, Iter it2 )
193 {
194     swap( *it1, *it2 );
195 }
196 
197 END_STD_SCOPE
198 
199 #if defined(_GLIBCXX_DEBUG)
200 /* STL iterators are non-POD types */
201 # define NCBI_NON_POD_TYPE_STL_ITERATORS  1
202 #endif
203 
204 #endif
205 
206 #ifdef NCBI_HAVE_CXX11
207 // Avoid (copious) warnings from using auto_ptr in C++ '11.
208 #  if defined(_GLIBCXX_DEPRECATED_ATTR)
209 #    include <string>
210 #    undef _GLIBCXX_DEPRECATED_ATTR
211 #    define _GLIBCXX_DEPRECATED_ATTR /* temporarily empty */
212 #    include <backward/auto_ptr.h>
213 #    undef _GLIBCXX_DEPRECATED_ATTR
214 #    define _GLIBCXX_DEPRECATED_ATTR NCBI_DEPRECATED
215 #  elif defined(_GLIBCXX_DEPRECATED)
216 #    include <string>
217 #    include <ext/concurrence.h>
218 #    ifdef _GLIBCXX_THROW_OR_ABORT /* using libstdc++ from GCC 4.8 or later */
219 #      include <typeinfo>
220 #      include <bits/alloc_traits.h>
221 #      include <bits/unique_ptr.h>
222 #      include <bits/shared_ptr.h>
223 #    endif
224 #    undef _GLIBCXX_DEPRECATED
225 #    define _GLIBCXX_DEPRECATED /* temporarily empty */
226 #    include <backward/auto_ptr.h>
227 #    undef _GLIBCXX_DEPRECATED
228 #    define _GLIBCXX_DEPRECATED NCBI_DEPRECATED
229 #  elif defined(_LIBCPP_DEPRECATED_IN_CXX11)
230 #    include <atomic>
231 #    include <cassert>
232 #    include <iterator>
233 #    include <stdexcept>
234 #    include <tuple>
235 #    undef _LIBCPP_DEPRECATED_IN_CXX11
236 #    define _LIBCPP_DEPRECATED_IN_CXX11 /**/
237 #    include <memory>
238 #    undef _LIBCPP_DEPRECATED_IN_CXX11
239 #    define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
240 #  endif
241 #endif
242 
243 #include <string>
244 BEGIN_NCBI_SCOPE
245 typedef std::string CStringUTF8;
246 END_NCBI_SCOPE
247 
248 
249 /// Helper template to check that type Type have some method declared
250 /// using TypeChecker<Type>.
251 ///
252 template <template <typename> class TypeChecker, typename Type>
253 struct cxx_is_supported
254 {
255     // these structs are used to recognize which version
256     // of the two functions was chosen during overload resolution
257     struct supported {};
258     struct not_supported {};
259 
260     // this overload of chk will be ignored by SFINAE principle
261     // if TypeChecker<Type_> is invalid type
262     template <typename Type_>
263     static supported chk(typename std::decay<TypeChecker<Type_>>::type *);
264 
265     // ellipsis has the lowest conversion rank, so this overload will be
266     // chosen during overload resolution only if the template overload above is ignored
267     template <typename Type_>
268     static not_supported chk(...);
269 
270     // if the template overload of chk is chosen during
271     // overload resolution then the feature is supported
272     // if the ellipses overload is chosen the the feature is not supported
273     static constexpr bool value = std::is_same<decltype(chk<Type>(nullptr)), supported>::value;
274 };
275 
276 
277 
278 /* @} */
279 
280 #endif /* NCBISTL__HPP */
281