1 /*
2  *
3  *  Copyright (C) 2014-2019, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  ofstd
15  *
16  *  Author:  Jan Schlamelcher
17  *
18  *  Purpose: Implement fallback support for modern techniques defined
19  *           in the STL's <utility> header (e.g. move semantics)
20  *           for older compilers.
21  */
22 
23 #ifndef OFUTIL_H
24 #define OFUTIL_H
25 
26 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
27 
28 #include "dcmtk/ofstd/oftraits.h"
29 #include "dcmtk/ofstd/oftypes.h"
30 
31 /** @file ofutil.h
32  *  Implement fallback support for modern techniques defined
33  *  in the STL's <utility> header (e.g.\ move semantics)
34  *  for older compilers.
35  */
36 
37 // -------------------- misc C++11 / non C++11 utils --------------------
38 
39 // The internet says <utility> should always be available, so we include
40 // it here to fix an issue with compilers that support std::tuple but
41 // not all of C++11 and perhaps other stuff.
42 #include <utility>
43 
44 #ifdef HAVE_STL_TUPLE
45 #include <tuple>
46 #endif
47 
48 #ifdef HAVE_CXX11
49 
50 #define OFmove std::move
51 #define OFswap std::swap
52 
53 // OFrvalue simply equals 'identity', as C++11 natively handles
54 // rvalues / prvalues and so on.
55 template<typename T>
56 using OFrvalue = T;
57 
58 #define OFrvalue_ref(T) T&&
59 #define OFrvalue_access(RV) RV
60 #define OFrvalue_ref_upcast(T, RV) static_cast<T&&>(RV)
61 
62 #else // fallback implementations
63 
64 #ifndef DOXYGEN
65 
66 // Meta-template to select the base class for OFrvalue
67 template<typename T,OFBool>
68 struct OFrvalue_storage
69 {
70     // Helper template to wrap types that we can't derive from,
71     // e.g. primitive types.
72     class type
73     {
74     public:
75         // copy constructor should be fine for primitive types.
typeOFrvalue_storage76         inline type(const T& pt)
77         : t( pt ) {}
typeOFrvalue_storage78         inline type(const OFrvalue_storage& rhs)
79         : t( rhs.pt ) {}
80 
81         // automatic conversion to the underlying type
82         inline operator T&() const { return OFconst_cast( T&, t ); }
83 
84     private:
85         // the actual object
86         T t;
87     };
88 };
89 
90 // specialization for compound types
91 template<typename T>
92 struct OFrvalue_storage<T,OFTrue>
93 {
94     // simply use T itself as base
95     typedef T type;
96 };
97 
98 // SFINAE to detect if a type is derivable from
99 template<typename T>
100 class OFrvalue_base
101 {
102     // magic SFINAE stuff stolen from en.cppreference.com
103     struct no_type {};
104     struct yes_type {double d;};
105     template<typename X>
106     static yes_type sfinae(int X::*);
107     template<typename X>
108     static no_type sfinae(...);
109 
110 public:
111     // employ SFINAE + template specialization to select
112     // the base type
113     typedef OFTypename OFrvalue_storage
114     <
115         T,
116         sizeof(sfinae<T>(OFnullptr)) == sizeof(yes_type)
117     >::type type;
118 };
119 
120 #endif // NOT DOXYGEN
121 
122 /** A helper class to 'tag' objects as <i>rvalues</i> to help
123  *  DCMTK's move emulation employed on pre C++11 compilers.
124  *  @tparam T the base type an rvalue should be create of.
125  *  @details OFrvalue wraps the type T inside a zero-overhead
126  *    object employing T's move constructor when possible.
127  *  @note When C++11 support is available, OFrvalue<T> will
128  *    simply be a type alias for <i>T</i>, since a C++11 compiler
129  *    handles rvalue reference conversions natively.
130  *  @details
131  *  <h2>Example</h2>
132  *  This example describes how to move an object of type
133  *  OFunique_ptr out of a function by using OFrvalue.
134  *  @code
135  *  OFrvalue<OFunique_ptr<DcmDataset> > getDataset()
136  *  {
137  *    return OFunique_ptr<DcmDataset>( new DcmDataset );
138  *  }
139  *  . . .
140  *  OFunique_ptr<DcmDataset> pDataset = getDataset();
141  *  @endcode
142  *  @warning Some compilers might require you to use the following
143  *    code instead, as older versions of the C++ standard allowed
144  *    the compiler to use the copy constructor for binding an
145  *    rvalue to an lvalue reference.
146  *    Use this code template instead to achieve maximum portability:
147  *  @code
148  *  OFrvalue<OFunique_ptr<DcmDataset> > getDataset()
149  *  {
150  *    OFunique_ptr<DcmDataset> pDataset( new DcmDataset );
151  *    return OFmove( pDataset );
152  *  }
153  *  @endcode
154  */
155 template<typename T>
156 struct OFrvalue : OFrvalue_base<T>::type
157 {
158 #ifndef DOXYGEN
159     // allow to move construct from lvalue references
160     inline OFrvalue(const T& t) : OFrvalue_base<T>::type( *OFreinterpret_cast( const OFrvalue*,  &t ) ) {}
161     // copy-construct from an rvalue reference
162     inline OFrvalue(const OFrvalue& rv) : OFrvalue_base<T>::type( rv ) {}
163     // poor man's in-place construction
164     template<typename X>
165     inline explicit OFrvalue( X x ) : OFrvalue_base<T>::type( x ) {}
166     template<typename X0,typename X1>
167     inline explicit OFrvalue( X0 x0, X1 x1 ) : OFrvalue_base<T>::type( x0, x1 ) {}
168     template<typename X0,typename X1,typename X2>
169     inline explicit OFrvalue( X0 x0, X1 x1, X2 x2 ) : OFrvalue_base<T>::type( x0, x1, x2 ) {}
170 #endif // NOT DOXYGEN
171 };
172 
173 #ifdef DOXYGEN
174 /** Determines <i>rvalue reference</i> type for the type <kbd>T</kbd>.
175  *  @param T the base type to determine the rvalue reference type for.
176  *  @note <i>OFrvalue_ref(T)</i> will expand to <kbd>T&&</kbd> when
177  *    C++11 support is available. Otherwise DCMTK's move emulation will
178  *    be used, employing an unspecified type to implement rvalue references.
179  *  @details
180  *  <h2>Example</h2>
181  *  This example shows how to implement the <i>move constructor</i> and
182  *  <i>move assignment</i> for a custom class in a portable fashion
183  *  (employing C++11's native features when available and using DCMTK's
184  *  move emulation otherwise).
185  *  @code
186  *  class MyMovable
187  *  {
188  *  public:
189  *    MyMovable( OFrvalue_ref(MyMovable) rhs )
190  *    : m_hDatabase( rhs.m_hDatabase )
191  *    {
192  *      // You need to use OFrvalue_access to get write access
193  *      // to rvalue references when DCMTK's move emulation
194  *      // is used.
195  *      OFrvalue_access(rhs).m_hDatabase = OFnullptr;
196  *    }
197  *
198  *    MyMovable& operator=( OFrvalue_ref(MyMovable) rvrhs )
199  *    {
200  *      // You may bind the rvalue reference to an lvalue
201  *      // reference to ease access.
202  *      MyMovable& rhs = OFrvalue_access(rvrhs);
203  *      if( this != &rhs )
204  *      {
205  *        disconnectDatabase( m_hDatabase );
206  *        m_hDatabase = rhs.m_hDatabase;
207  *        rhs.m_hDatabase = OFnullptr;
208  *      }
209  *      return *this;
210  *    }
211  *  };
212  *  @endcode
213  */
214 #define OFrvalue_ref(T) unspecified
215 
216 /** Upcast an rvalue reference to an rvalue reference of one of its bases.
217  *  This is a helper macro for being used with DCMTK's fallback implementation
218  *  of move semantics. C++11 rvalue references should normally allow implicit
219  *  upcasts, therefore, this macro typically has no effect if C++11 is enabled
220  *  (it may be used to work around the behavior of older GCC versions).
221  *  @param T the base class to upcast to
222  *  @param RV the rvalue reference to upcast
223  */
224 #define OFrvalue_ref_upcast(T, RV) unspecified
225 #else // NOT DOXYGEN
226 #define OFrvalue_ref(T) const OFrvalue<T >&
227 #define OFrvalue_ref_upcast(T, RV) OFmove<T >(RV)
228 #endif
229 
230 /** Obtain an lvalue reference from an rvalue reference.
231  *  DCMTK's move emulations does restrict write access to rvalue references
232  *  due to compiler limitations.
233  *  This method enables you to workaround this restriction by converting
234  *  DCMTK's emulated rvalue references to lvalue references.
235  *  @note Native rvalue references from C++11 don't need this workaround,
236  *   therefore <i>OFrvalue_access</i> has no effect when C++11 support is
237  *   available.
238  *  @param rv an rvalue reference, e.g. the parameter of a <i>move constructor</i>.
239  */
240 template<typename T>
241 T& OFrvalue_access( OFrvalue_ref(T) rv )
242 {
243 #ifndef DOXYGEN
244     return OFconst_cast( OFrvalue<T>&, rv );
245 #endif
246 }
247 
248 /** Obtains an rvalue reference to its argument and converts it
249  *  to an xvalue. OFmove is meant to 'mark' an object for a
250  *  move operation, e.g. to move an OFVector object into another
251  *  OFVector instance instead of copying it.
252  *  @note OFmove will be an alias for std::move when native
253  *    move semantics are supported (C++11 support is available).
254  *    Otherwise DCMTK's move emulation will be used. This means
255  *    you will have to specify rvalues (e.g. function return values)
256  *    employing the OFrvalue class template.
257  *  @param t The object to move.
258  *  @see OFrvalue
259  *  @see OFrvalue_ref
260  */
261 template<typename T>
262 #ifndef DOXYGEN
263 OFrvalue<T>& OFmove( T& t )
264 {
265     return *OFreinterpret_cast( OFrvalue<T>*, &t );
266 }
267 
268 template<typename T>
269 OFrvalue<T>& OFmove( OFrvalue<T>& rv )
270 {
271     return rv;
272 }
273 
274 template<typename T>
275 OFrvalue<T>& OFmove( const OFrvalue<T>& rv )
276 {
277     return OFconst_cast( OFrvalue<T>&, rv );
278 }
279 #else // NOT DOXYGEN
280 OFconstexpr xvalue OFmove( T< unspecified > t );
281 #endif // DOXYGEN
282 
283 /** Exchanges the given values.
284  *  OFswap is an alias for std::swap if C++11 is supported.
285  *  Otherwise OFswap simply creates a temporary copy of one
286  *  argument to exchange both values.
287  *  @note As intended for std::swap, there are some
288  *    specializations for OFswap available, e.g. for OFoptional,
289  *    which specializes OFswap to exchange optional objects
290  *    more efficiently. When creating your own specializations
291  *    for OFswap, make sure to specialize std::swap instead
292  *    when C++11 support is available.
293  *  @param t0 An object to be exchanged.
294  *  @param t1 The object to be exchanged with t0.
295  */
296 template<typename T>
297 void OFswap( T& t0, T& t1 )
298 #ifndef DOXYGEN
299 {
300     T temp( OFmove( t0 ) );
301     t0 = OFmove( t1 );
302     t1 = OFmove( temp );
303 }
304 #else // NOT DOXYGEN
305 ;
306 #endif // DOXYGEN
307 
308 #endif // NOT C++11
309 
310 // -------------------- STL pair --------------------
311 
312 #ifdef HAVE_STL_MAP
313 
314 // Use native pair class, to be compatible to std::map
315 #define OFPair std::pair
316 #define OFMake_pair std::make_pair
317 
318 #else // fallback implementation of std::pair
319 
320 /** a pair - this implements parts of std::pair's interface.
321  */
322 template<typename K, typename V> class OFPair
323 {
324 public:
325 
326     /** this is the first value of the pair */
327     K first;
328 
329     /** this is the second value of the pair */
330     V second;
331 
332     /** default constructor */
333     OFPair() : first(), second() { }
334 
335     /** construct a OFPair for the two given values
336      *  @param f the value for first.
337      *  @param s the value for second.
338      */
339     OFPair(const K& f, const V& s) : first(f), second(s) { }
340 
341     /** copy constructor
342      *  @param p Other OFPair to copy from.
343      */
344     template<class OK, class OV>
345     OFPair(const OFPair<OK, OV>& p) : first(p.first), second(p.second) { }
346 
347     /** copy constructor
348      *  @param p Other OFPair to copy from.
349      */
350     OFPair(const OFPair& p) : first(p.first), second(p.second) { }
351 
352     /** assignment operator */
353     OFPair<K, V>& operator=(const OFPair<K, V>& other)
354     {
355         first = other.first;
356         second = other.second;
357         return *this;
358     }
359 };
360 
361 /** helper function to create a pair. This is similar to std::make_pair()
362  *  @param first the first part of the pair
363  *  @param second the second art of the pair
364  *  @relates OFPair
365  *  @return the pair (first, second)
366  */
367 template<typename K, typename V>
368 OFPair<K, V> OFMake_pair(const K& first, const V& second)
369 {
370     return OFPair<K, V>(first, second);
371 }
372 
373 #endif // HAVE_STL_MAP - fallback implementation of OFPair
374 
375 // -------------------- STL tuple --------------------
376 
377 #ifdef HAVE_STL_TUPLE
378 
379 #ifdef HAVE_CXX11
380 
381 template<std::size_t Index,typename T>
382 constexpr auto OFget( T&& t ) -> decltype( std::get<Index>( std::forward<T>( t ) ) )
383 {
384     return std::get<Index>( std::forward<T>( t ) );
385 }
386 
387 template<typename X,typename T>
388 constexpr auto OFget( T&& t ) -> decltype( std::get<X>( std::forward<T>( t ) ) )
389 {
390     return std::get<X>( std::forward<T>( t ) );
391 }
392 
393 template<typename Tuple>
394 using OFtuple_size = std::tuple_size<Tuple>;
395 
396 template<std::size_t Index,typename Tuple>
397 using OFtuple_element = std::tuple_element<Index,Tuple>;
398 
399 #else // HAVE_CXX11
400 
401 template<typename Tuple>
402 struct OFtuple_size : STD_NAMESPACE tuple_size<Tuple> {};
403 
404 template<size_t Index,typename Tuple>
405 struct OFtuple_element : STD_NAMESPACE tuple_element<Index,Tuple> {};
406 
407 template<size_t Index,typename T>
408 OFTypename OFtuple_element<Index,T>::type OFget( T& t ) { return STD_NAMESPACE get<Index>( t ); }
409 
410 template<size_t Index,typename T>
411 OFTypename OFtuple_element<Index,T>::type OFget( const T& t ) { return STD_NAMESPACE get<Index>( t ); }
412 
413 #endif // NOT HAVE_CXX11
414 
415 #else // HAVE_STL_TUPLE
416 
417 template<typename Tuple>
418 struct OFtuple_size;
419 template<size_t Index,typename Tuple>
420 struct OFtuple_element;
421 
422 // specialization of OFtuple_size for OFPair -> 2
423 template<typename K,typename V>
424 struct OFtuple_size<OFPair<K,V> >
425 : OFintegral_constant<size_t,2> {};
426 
427 // specialization of OFtuple_element for OFPair
428 // 0 -> K
429 template<typename K,typename V>
430 struct OFtuple_element<0,OFPair<K,V> >
431 {
432     typedef K type;
433 };
434 
435 // specialization of OFtuple_element for OFPair
436 // 1 -> V
437 template<typename K,typename V>
438 struct OFtuple_element<1,OFPair<K,V> >
439 {
440     typedef V type;
441 };
442 
443 // metafunction to apply OFget to OFPair
444 template<size_t Element>
445 struct OFpair_element;
446 
447 // specialization for 0 -> first
448 template<>
449 struct OFpair_element<0>
450 {
451     template<typename K,typename V>
452     static K& from( OFPair<K,V>& p ) { return p.first; }
453     template<typename K,typename V>
454     static const K& from( const OFPair<K,V>& p ) { return p.first; }
455 };
456 
457 // specialization for 1 -> second
458 template<>
459 struct OFpair_element<1>
460 {
461     template<typename K,typename V>
462     static V& from( OFPair<K,V>& p ) { return p.second; }
463     template<typename K,typename V>
464     static const V& from( const OFPair<K,V>& p ) { return p.second; }
465 };
466 
467 // overload of OFget for OFPair, see above metafunction 'OFpair_element'
468 template<size_t Element,typename K,typename V>
469 typename OFtuple_element<Element,OFPair<K,V> >::type& OFget( OFPair<K,V>& p )
470 {
471     return OFpair_element<Element>::from( p );
472 }
473 
474 // overload of OFget for const OFPair, see above metafunction 'OFpair_element'
475 template<size_t Element,typename K,typename V>
476 const typename OFtuple_element<Element,OFPair<K,V> >::type& OFget( const OFPair<K,V>& p )
477 {
478     return OFpair_element<Element>::from( p );
479 }
480 
481 // tag to identify invalid OFtuple elements, needed for emulating
482 // variadic templates.
483 struct OFtuple_nil;
484 
485 // include generated forward declaration for OFtuple.
486 #include "dcmtk/ofstd/variadic/tuplefwd.h"
487 
488 #endif // HAVE_STL_TUPLE
489 
490 #ifdef DOXYGEN // doxygen documentation of OFtuple utils
491 
492 /** A metafunction to determine the size of a tuple.
493  *  @tparam Tuple a tuple type, e.g. an instance of OFtuple.
494  *  @pre Tuple is a tuple type, see @ref tuple_types "Tuple Types"
495  *    for definition.
496  *  @return OFtuple_size is derived from an appropriate instance of
497  *    OFintegral_constant if the preconditions are met. This means
498  *    OFtuple_size declares a static member constant <i>value</i>
499  *    set to the tuple's size.
500  *  @relates OFPair
501  *  @relates OFtuple
502  *  @details
503  *  <h3>Usage Example:</h3>
504  *  @code{.cpp}
505  *  typedef OFtuple<OFString,size_t,OFVector<int> > MyTuple;
506  *  typedef OFPair<OFString,MyTuple> MyPair;
507  *  COUT << "OFtuple_size<MyTuple>::value: " << OFtuple_size<MyTuple>::value << OFendl;
508  *  COUT << "OFtuple_size<MyPair>::value: " << OFtuple_size<MyPair>::value << OFendl;
509  *  @endcode
510  *  <b>Output:</b>
511  *  @verbatim
512     OFtuple_size<MyTuple>::value: 3
513     OFtuple_size<MyPair>::value: 2
514     @endverbatim
515  *
516  */
517 template<typename Tuple>
518 <metafunction> OFtuple_size;
519 
520 /** A metafunction to determine the type of one element of a tuple.
521  *  @tparam Index the index of the element its type should be determined.
522  *  @tparam Tuple a tuple type, e.g. an instance of OFtuple.
523  *  @pre Tuple is a tuple type, see @ref tuple_types "Tuple Types"
524  *    for definition.
525  *  @pre Index is a valid index , essentially: <kbd>Index < OFtuple_size<Tuple>::value</kbd>.
526  *  @return if the preconditions are met, OFtuple_element declares a member
527  *    type alias <i>type</i> that yields the type of the element at the given index.
528  *  @relates OFtuple
529  *  @details
530  *  <h3>Usage Example:</h3>
531  *  @code{.cpp}
532  *  typedef OFPair<OFString,size_t> MyPair;
533  *  typedef OFtuple<OFtuple_element<0,MyPair>::type,OFtuple_element<1,MyPair>::type> MyTuple;
534  *  MyPair pair( "Hello World", 42 );
535  *  MyTuple tuple( pair ); // Works, since both elements' types are the same as within MyPair.
536  *  @endcode
537  *
538  */
539 template<size_t Index,typename Tuple>
540 <metafunction> OFtuple_element;
541 
542 /** A function template to access an element of a tuple.
543  *  @tparam Index the index of the element that should be accessed.
544  *  @tparam Tuple a tuple type, e.g. an instance of OFtuple. This parameter
545  *    is deduced automatically.
546  *  @param tuple a reference to the tuple to access an element of.
547  *  @pre Tuple is a tuple type, see @ref tuple_types "Tuple Types"
548  *    for definition.
549  *  @pre Index is a valid index , essentially: <kbd>Index < OFtuple_size<Tuple>::value</kbd>.
550  *  @return a reference to the tuple's element at the given index.
551  *  @relates OFtuple
552  *  @details
553  *  <h3>Usage Example:</h3>
554  *  @code{.cpp}
555  *  OFtuple<OFString,size_t,OFVector<int> > myTuple;
556  *  OFget<0>( myTuple ) = "Hamish Alexander";
557  *  OFget<1>( myTuple ) = 23;
558  *  OFget<2>( myTuple ).push_back( 42 );
559  *  @endcode
560  */
561 template<size_t Index,typename Tuple>
562 typename OFtuple_element<Index,Tuple>::type& OFget( Tuple& tuple );
563 
564 /** A function template to access an element of a tuple.
565  *  @tparam Index the index of the element that should be accessed.
566  *  @tparam Tuple a tuple type, e.g. an instance of OFtuple. This parameter
567  *    is deduced automatically.
568  *  @param tuple a const reference to the tuple to access an element of.
569  *  @pre Tuple is a tuple type, see @ref tuple_types "Tuple Types"
570  *    for definition.
571  *  @pre Index is a valid index , essentially: <kbd>Index < OFtuple_size<Tuple>::value</kbd>.
572  *  @return a const reference to the tuple's element at the given index.
573  *  @relates OFtuple
574  *  @details
575  *  <h3>Usage Example:</h3>
576  *  @code{.cpp}
577  *  const OFtuple<OFString,size_t,OFBool> myConstTuple( "Homer Simpson", 38, OFTrue );
578  *  if( OFget<0>( myConstTuple ) == "Homer Simpson" )
579  *  {
580  *    // OFget<1>( myConstTuple ) = 23; INVALID, myConstTuple is const!
581  *    OFBool isMale = OFget<2>( myConstTuple );
582  *    if( isMale )
583  *      COUT << OFget<0>( myConstTuple ) << ", age "
584  *           << OFget<1>( myConstTuple ) << " is male." << OFendl;
585  *  }
586  *  @endcode
587  *  <b>Output:</b>
588  *  @verbatim
589     Homer Simpson, age 38 is male.
590     @endverbatim
591  */
592 template<size_t Index,typename Tuple>
593 const typename OFtuple_element<Index,Tuple>::type& OFget( const Tuple& tuple );
594 #endif // DOXYGEN
595 
596 // -------------------- misc utils (OFinplace etc.) --------------------
597 
598 #ifndef DOXYGEN
599 
600 // OFin_place hacks, look at the doxygen documentation instead if
601 // you know what's good for you!
602 class DCMTK_OFSTD_EXPORT OFin_place_tag { OFin_place_tag(); };
603 typedef OFin_place_tag(&OFin_place_t)();
604 #define OFin_place_type_t(T) OFin_place_tag(&)(T&)
605 #define OFin_place_index_t(I) OFin_place_tag(&)(OFintegral_constant<size_t,I>&)
606 DCMTK_OFSTD_EXPORT OFin_place_tag OFin_place();
607 template<typename T>
608 OFin_place_tag OFin_place(T&) { return OFin_place(); }
609 template<size_t I>
610 OFin_place_tag OFin_place(OFintegral_constant<size_t,I>&) { return OFin_place(); }
611 
612 #else // NOT DOXYGEN
613 
614 /** @defgroup OFin_place_helpers_brief
615  *  @details Tools for in-place construction of objects, e.g. certain OFvariant alternatives.
616  *  @defgroup OFin_place_helpers Tools for in-place construction
617  *  @details
618  *  <b><em style="color:#7f0000">#include</em> <span class="keyword">"dcmtk/ofstd/ofutil.h"</span></b><br><br>
619  *  @copydoc OFin_place_helpers_brief
620  *  <table class="memberdecls">
621  *    <tr class="heading">
622  *      <td colspan="2"><div><h2 class="groupheader">Type Definitions</h2></div></td>
623  *    </tr>
624  *    <tr>
625  *      <td class="memItemLeft" align="right" valign="top"><span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em></td>
626  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_t">OFin_place_t</a></td>
627  *    </tr>
628  *    <tr>
629  *      <td class="mdescLeft"></td>
630  *      <td class="mdescRight">A type for tagging an in-place constructor as such. <a href="#OFin_place_t">More...</a></td>
631  *    </tr>
632  *    <tr><td class="memSeparator" colspan="2"></td></tr>
633  *    <tr><td class="memTemplParams" colspan="2">template&lt;typename T&gt;</td></tr>
634  *    <tr>
635  *      <td class="memItemLeft" align="right" valign="top"><span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em></td>
636  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_type_t">OFin_place_type_t(T)</a></td>
637  *    </tr>
638  *    <tr>
639  *      <td class="mdescLeft"></td>
640  *      <td class="mdescRight">A type for tagging an in-place constructor for a certain type as such. <a href="#OFin_place_type_t">More...</a></td>
641  *    </tr>
642  *    <tr><td class="memSeparator" colspan="2"></td></tr>
643  *    <tr><td class="memTemplParams" colspan="2">template&lt;size_t I&gt;</td></tr>
644  *    <tr>
645  *      <td class="memItemLeft" align="right" valign="top"><span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em></td>
646  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_index_t">OFin_place_index_t(I)</a></td>
647  *    </tr>
648  *    <tr>
649  *      <td class="mdescLeft"></td>
650  *      <td class="mdescRight">A type for tagging an in-place constructor based on a certain index  as such. <a href="#OFin_place_index_t">More...</a></td>
651  *    </tr>
652  *    <tr><td class="memSeparator" colspan="2"></td></tr>
653  *  </table>
654  *  <table class="memberdecls">
655  *    <tr class="heading">
656  *      <td colspan="2"><div><h2 class="groupheader">Global Constants</h2></div></td>
657  *    </tr>
658  *    <tr>
659  *      <td class="memItemLeft" align="right" valign="top"><a href="#OFin_place_t">OFin_place_t</a></td>
660  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_generic">OFin_place</a></td>
661  *    </tr>
662  *    <tr>
663  *      <td class="mdescLeft"></td>
664  *      <td class="mdescRight">
665  *        A constant of type <a href="#OFin_place_t">OFin_place_t</a> that may be used for in-place construction.
666  *        <a href="#OFin_place_generic">More...</a>
667  *      </td>
668  *    </tr>
669  *    <tr><td class="memSeparator" colspan="2"></td></tr>
670  *    <tr><td class="memTemplParams" colspan="2">template&lt;typename T&gt;</td></tr>
671  *    <tr>
672  *      <td class="memItemLeft" align="right" valign="top"><a href="#OFin_place_type_t">OFin_place_type_t(T)</a></td>
673  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_type">OFin_place&lt;T&gt;</a></td>
674  *    </tr>
675  *    <tr>
676  *      <td class="mdescLeft"></td>
677  *      <td class="mdescRight">
678  *        A constant of type <a href="#OFin_place_type_t">OFin_place_type_t(T)</a> that may be used for in-place construction.
679  *        <a href="#OFin_place_type">More...</a>
680  *      </td>
681  *    </tr>
682  *    <tr><td class="memSeparator" colspan="2"></td></tr>
683  *    <tr><td class="memTemplParams" colspan="2">template&lt;size_t I&gt;</td></tr>
684  *    <tr>
685  *      <td class="memItemLeft" align="right" valign="top"><a href="#OFin_place_index_t">OFin_place_index_t(I)</a></td>
686  *      <td class="memItemRight" valign="bottom"><a href="#OFin_place_index">OFin_place&lt;I&gt;</a></td>
687  *    </tr>
688  *    <tr>
689  *      <td class="mdescLeft"></td>
690  *      <td class="mdescRight">
691  *        A constant of type <a href="#OFin_place_index_t">OFin_place_index_t(I)</a> that may be used for in-place construction.
692  *        <a href="#OFin_place_index">More...</a>
693  *      </td>
694  *    </tr>
695  *    <tr><td class="memSeparator" colspan="2"></td></tr>
696  *  </table>
697  *  <h2 class="groupheader">Type Definition Documentation</h2>
698  *  @anchor OFin_place_t
699  *  <div class="memitem">
700  *    <div class="memproto">
701  *      <div class="memname">
702  *        <span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em> OFin_place_t
703  *      </div>
704  *    </div>
705  *    <div class="memdoc">
706  *      <br>A type for tagging an in-place constructor as such.<br>
707  *      <dl></dl>
708  *      <b>Usage Example:</b><br>
709  *      @code{.cpp}
710  *      template<typename T>
711  *      class Wrapper
712  *      {
713  *      public:
714  *        // Will copy construct the wrapped value from a T.
715  *        Wrapper( const T& t );
716  *
717  *        // Will in-place construct the value from the given arguments,
718  *        // calling T( arguments... ) internally, without unnecessary
719  *        // copies.
720  *        template<typename... Arguments>
721  *        Wrapper( OFin_place_t, Arguments... arguments );
722  *
723  *      private:
724  *        // ... wrapper implementation ...
725  *      };
726  *      @endcode
727  *    </div>
728  *  </div>
729  *  @anchor OFin_place_type_t
730  *  <div class="memitem">
731  *    <div class="memproto">
732  *      <div class="memtemplate">template<typename T></div>
733  *      <div class="memname">
734  *        <span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em> OFin_place_type_t(T)
735  *      </div>
736  *    </div>
737  *    <div class="memdoc">
738  *      <br>A type for tagging an in-place constructor for a certain type as such.
739  *      <br>
740  *      <dl class="tparams">
741  *        <dt>Template Parameters<dt>
742  *        <dd><span class="paramname">T</span> the type this in-pace constructor handles, i.e. the type that will be constructed.</dd>
743  *      </dl>
744  *      @note Pre C++11 compilers do not support alias templates, therefore, OFin_place_type_t is implemented
745  *        using preprocessor macros internally. This is why you need to use curved brackets instead of angled ones.
746  *
747  *      <b>Usage Example:</b><br>
748  *      @code{.cpp}
749  *      template<typename A,typename B>
750  *      class Union
751  *      {
752  *      public:
753  *        // Will copy construct the wrapped value as an A from a.
754  *        Union( const A& a );
755  *
756  *        // Will copy construct the wrapped value as a B from b.
757  *        Union( const B& b );
758  *
759  *        // Will in-place construct the value as an A from the given
760  *        // arguments, calling A( arguments... ) internally, without
761  *        // unnecessary copies.
762  *        template<typename... Arguments>
763  *        Union( OFin_place_type_t(A), Arguments... arguments );
764  *
765  *        // Will in-place construct the value as a B from the given
766  *        // arguments, calling B( arguments... ) internally, without
767  *        // unnecessary copies.
768  *        template<typename... Arguments>
769  *        Union( OFin_place_type_t(B), Arguments... arguments );
770  *
771  *      private:
772  *        // ... union implementation ...
773  *      };
774  *      @endcode
775  *    </div>
776  *  </div>
777  *  @anchor OFin_place_index_t
778  *  <div class="memitem">
779  *    <div class="memproto">
780  *      <div class="memtemplate">template<size_t I></div>
781  *      <div class="memname">
782  *        <span class="keyword">typedef</span> <em style="color:#7f0000;opacity:.7">unspecified</em> OFin_place_index_t(I)
783  *      </div>
784  *    </div>
785  *    <div class="memdoc">
786  *      <br>A type for tagging an in-place constructor for a certain index as such.<br>
787  *      <dl class="tparams">
788  *        <dt>Template Parameters<dt>
789  *        <dd>
790  *          <span class="paramname">I</span> the index this in-pace constructor handles, i.e. the zero
791  *          based index of the type that will be constructed.
792  *        </dd>
793  *      </dl>
794  *      @note Pre C++11 compilers do not support alias templates, therefore, OFin_place_index_t is implemented
795  *        using preprocessor macros internally. This is why you need to use curved brackets instead of angled ones.
796  *
797  *      <b>Usage Example:</b><br>
798  *      @code{.cpp}
799  *      template<typename A,typename B>
800  *      class Union
801  *      {
802  *      public:
803  *        // Will copy construct the wrapped value as an A from a.
804  *        Union( const A& a );
805  *
806  *        // Will copy construct the wrapped value as a B from b.
807  *        Union( const B& b );
808  *
809  *        // Will in-place construct the value as an A from the given
810  *        // arguments, calling A( arguments... ) internally, without
811  *        // unnecessary copies.
812  *        // This will even work if A and B refer to the same type.
813  *        template<typename... Arguments>
814  *        Union( OFin_place_index_t(0), Arguments... arguments );
815  *
816  *        // Will in-place construct the value as a B from the given
817  *        // arguments, calling B( arguments... ) internally, without
818  *        // unnecessary copies.
819  *        // This will even work if A and B refer to the same type.
820  *        template<typename... Arguments>
821  *        Union( OFin_place_index_t(1), Arguments... arguments );
822  *
823  *      private:
824  *        // ... union implementation ...
825  *      };
826  *      @endcode
827  *    </div>
828  *  </div>
829  *  <h2 class="groupheader">Global Constant Documentation</h2>
830  *  @anchor OFin_place_generic
831  *  <div class="memitem">
832  *    <div class="memproto">
833  *      <div class="memname">
834  *        <a href="#OFin_place_t">OFin_place_t</a> OFin_place
835  *      </div>
836  *    </div>
837  *    <div class="memdoc">
838  *      <br>A constant of type <a href="#OFin_place_t">OFin_place_t</a> that may be used for in-place construction.<br>
839  *      @remarks OFin_place is actually an overloaded function, but instead of calling it
840  *        (which one should never do), its address is used as a tag, since the type of
841  *        its address differs depending on which overload and template parameters are used.
842  *        See http://en.cppreference.com/w/cpp/utility/in_place for more information.
843  *
844  *      <b>Usage Example:</b><br>
845  *      @code{.cpp}
846  *      template<typename T>
847  *      class Wrapper; // see OFin_place_t example
848  *      // ...
849  *      // will construct an OFString and then copy construct the value in the wrapper
850  *      Wrapper<OFString>( "Hello World" );
851  *      // will in-place construct the value in the wrapper
852  *      Wrapper<OFString>( OFin_place, "Hello World" );
853  *      // this also works with multiple arguments:
854  *      // will take only the fist five characters of the const char*
855  *      Wrapper<OFString>( OFin_place, "Hello World", 5 );
856  *      @endcode
857  *    </div>
858  *  </div>
859  *  @anchor OFin_place_type
860  *  <div class="memitem">
861  *    <div class="memproto">
862  *      <div class="memtemplate">template<typename T></div>
863  *      <div class="memname">
864  *        <a href="#OFin_place_type_t">OFin_place_type_t(T)</a> OFin_place<T>
865  *      </div>
866  *    </div>
867  *    <div class="memdoc">
868  *      <br>A constant of type <a href="#OFin_place_type_t">OFin_place_type_t(T)</a> that may be used for in-place construction.<br>
869  *      <dl class="tparams">
870  *        <dt>Template Parameters<dt>
871  *        <dd><span class="paramname">T</span> the type for selecting an in-pace constructor, i.e. the type that will be constructed.</dd>
872  *      </dl>
873  *      @remarks OFin_place is actually an overloaded function, but instead of calling it
874  *        (which one should never do), its address is used as a tag, since the type of
875  *        its address differs depending on which overload and template parameters are used.
876  *        See http://en.cppreference.com/w/cpp/utility/in_place for more information.
877  *
878  *      <b>Usage Example:</b><br>
879  *      @code{.cpp}
880  *      template<typename A,typename B>
881  *      class Union; // see OFin_place_type_t example
882  *      // ...
883  *      // will construct an OFString and then copy construct the value inside the union
884  *      Union<int,OFString>( OFString( "Hello World" ) );
885  *      // will in-place construct an OFString value inside the union
886  *      // with only the fist five characters
887  *      Union<int,OFString>( OFin_place<OFString>, "Hello World", 5 );
888  *      // will construct an integer value inside the union by casting
889  *      // the address of the character array constant to int
890  *      Union<int,OFString>( OFin_place<int>, "Hello World" );
891  *      @endcode
892  *    </div>
893  *  </div>
894  *  @anchor OFin_place_index
895  *  <div class="memitem">
896  *    <div class="memproto">
897  *      <div class="memtemplate">template<size_t I></div>
898  *      <div class="memname">
899  *        <a href="#OFin_place_index_t">OFin_place_index_t(I)</a> OFin_place&lt;I&gt;
900  *      </div>
901  *    </div>
902  *    <div class="memdoc">
903  *      <br>A constant of type <a href="#OFin_place_index_t">OFin_place_index_t(I)</a> that may be used for in-place construction.<br>
904  *      <dl class="tparams">
905  *        <dt>Template Parameters<dt>
906  *        <dd>
907  *          <span class="paramname">I</span> the index for selecting an in-pace constructor, i.e. the
908  *          zero based index of the type that will be constructed.
909  *        </dd>
910  *      </dl>
911  *      @remarks OFin_place is actually an overloaded function, but instead of calling it
912  *        (which one should never do), its address is used as a tag, since the type of
913  *        its address differs depending on which overload and template parameters are used.
914  *        See http://en.cppreference.com/w/cpp/utility/in_place for more information.
915  *
916  *      <b>Usage Example:</b><br>
917  *      @code{.cpp}
918  *      template<typename A,typename B>
919  *      class Union; // see OFin_place_index_t example
920  *      // ...
921  *      // error, cannot determine which constructor shall be used,
922  *      // since both take an int
923  *      Union<int,int>( 3 );
924  *      // will in-place construct an int value inside the union
925  *      // tagging it as an A
926  *      Union<int,int>( OFin_place<0>, 3 );
927  *      // will in-place construct an int value inside the union
928  *      // tagging it as a B
929  *      Union<int,int>( OFin_place<1>, 3 );
930  *      @endcode
931  *    </div>
932  *  </div>
933  */
934 
935 #endif // DOXYGEN
936 
937 #endif // OFUTIL_H
938