Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:20

0001 // Copyright (C) 2017 Andrzej Krzemienski.
0002 //
0003 // Use, modification, and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/optional for documentation.
0008 //
0009 // You are welcome to contact the author at:
0010 //  akrzemi1@gmail.com
0011 
0012 // trivially-copyable version of the storage
0013 
0014 template<class T>
0015 class tc_optional_base : public optional_tag
0016 {
0017   private :
0018 
0019     typedef tc_optional_base<T> this_type ;
0020 
0021   protected :
0022 
0023     typedef T value_type ;
0024 
0025   protected:
0026     typedef T &       reference_type ;
0027     typedef T const&  reference_const_type ;
0028 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0029     typedef T &&  rval_reference_type ;
0030     typedef T &&  reference_type_of_temporary_wrapper ;
0031 #endif
0032     typedef T *         pointer_type ;
0033     typedef T const*    pointer_const_type ;
0034     typedef T const&    argument_type ;
0035 
0036     tc_optional_base()
0037       :
0038       m_initialized(false) {}
0039 
0040     tc_optional_base ( none_t )
0041       :
0042       m_initialized(false) {}
0043 
0044     tc_optional_base ( init_value_tag, argument_type val )
0045       :
0046       m_initialized(true), m_storage(val) {}
0047 
0048     tc_optional_base ( bool cond, argument_type val )
0049       :
0050       m_initialized(cond), m_storage(val) {}
0051 
0052     // tc_optional_base ( tc_optional_base const& ) = default;
0053 
0054 
0055 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0056 
0057     template<class Expr, class PtrExpr>
0058     explicit tc_optional_base ( Expr&& expr, PtrExpr const* tag )
0059       :
0060       m_initialized(false)
0061     {
0062       construct(boost::forward<Expr>(expr),tag);
0063     }
0064 
0065 #else
0066     // This is used for both converting and in-place constructions.
0067     // Derived classes use the 'tag' to select the appropriate
0068     // implementation (the correct 'construct()' overload)
0069     template<class Expr>
0070     explicit tc_optional_base ( Expr const& expr, Expr const* tag )
0071       :
0072       m_initialized(false)
0073     {
0074       construct(expr,tag);
0075     }
0076 
0077 #endif
0078 
0079     // tc_optional_base& operator= ( tc_optional_base const& ) = default;
0080     // ~tc_optional_base() = default;
0081 
0082     // Assigns from another optional<T> (deep-copies the rhs value)
0083     void assign ( tc_optional_base const& rhs )
0084     {
0085       *this = rhs;
0086     }
0087 
0088     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
0089     template<class U>
0090     void assign ( optional<U> const& rhs )
0091     {
0092       if ( rhs.is_initialized() )
0093 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0094         m_storage = rhs.get();
0095 #else
0096         m_storage = static_cast<value_type>(rhs.get());
0097 #endif
0098 
0099       m_initialized = rhs.is_initialized();
0100     }
0101 
0102 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0103     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
0104     template<class U>
0105     void assign ( optional<U>&& rhs )
0106     {
0107       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
0108       if ( rhs.is_initialized() )
0109         m_storage = static_cast<ref_type>(rhs.get());
0110       m_initialized = rhs.is_initialized();
0111     }
0112 #endif
0113 
0114     void assign ( argument_type val )
0115     {
0116       construct(val);
0117     }
0118 
0119     void assign ( none_t ) { destroy(); }
0120 
0121 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0122 
0123 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0124     template<class Expr, class ExprPtr>
0125     void assign_expr ( Expr&& expr, ExprPtr const* tag )
0126     {
0127        construct(boost::forward<Expr>(expr),tag);
0128     }
0129 #else
0130     template<class Expr>
0131     void assign_expr ( Expr const& expr, Expr const* tag )
0132     {
0133       construct(expr,tag);
0134     }
0135 #endif
0136 
0137 #endif
0138 
0139   public :
0140 
0141     // Destroys the current value, if any, leaving this UNINITIALIZED
0142     // No-throw (assuming T::~T() doesn't)
0143     void reset() BOOST_NOEXCEPT { destroy(); }
0144 
0145     // **DEPRECATED** Replaces the current value -if any- with 'val'
0146     void reset ( argument_type val ) BOOST_NOEXCEPT { assign(val); }
0147 
0148     // Returns a pointer to the value if this is initialized, otherwise,
0149     // returns NULL.
0150     // No-throw
0151     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
0152     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
0153 
0154     bool is_initialized() const { return m_initialized ; }
0155 
0156   protected :
0157 
0158     void construct ( argument_type val )
0159      {
0160        m_storage = val ;
0161        m_initialized = true ;
0162      }
0163 
0164 
0165 #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0166     // Constructs in-place
0167     // upon exception *this is always uninitialized
0168     template<class... Args>
0169     void construct ( in_place_init_t, Args&&... args )
0170     {
0171       m_storage = value_type( boost::forward<Args>(args)... ) ;
0172       m_initialized = true ;
0173     }
0174 
0175     template<class... Args>
0176     void emplace_assign ( Args&&... args )
0177     {
0178       construct(in_place_init, boost::forward<Args>(args)...);
0179     }
0180 
0181     template<class... Args>
0182     explicit tc_optional_base ( in_place_init_t, Args&&... args )
0183       :
0184       m_initialized(false)
0185     {
0186       construct(in_place_init, boost::forward<Args>(args)...);
0187     }
0188 
0189     template<class... Args>
0190     explicit tc_optional_base ( in_place_init_if_t, bool cond, Args&&... args )
0191       :
0192       m_initialized(false)
0193     {
0194       if ( cond )
0195         construct(in_place_init, boost::forward<Args>(args)...);
0196     }
0197 #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
0198     template<class Arg>
0199     void construct ( in_place_init_t, Arg&& arg )
0200      {
0201        m_storage = value_type( boost::forward<Arg>(arg) );
0202        m_initialized = true ;
0203      }
0204 
0205     void construct ( in_place_init_t )
0206      {
0207        m_storage = value_type();
0208        m_initialized = true ;
0209      }
0210 
0211     template<class Arg>
0212     void emplace_assign ( Arg&& arg )
0213      {
0214        construct(in_place_init, boost::forward<Arg>(arg)) ;
0215      }
0216 
0217     void emplace_assign ()
0218      {
0219        construct(in_place_init) ;
0220      }
0221 
0222     template<class Arg>
0223     explicit tc_optional_base ( in_place_init_t, Arg&& arg )
0224       :
0225       m_initialized(false)
0226     {
0227       construct(in_place_init, boost::forward<Arg>(arg));
0228     }
0229 
0230     explicit tc_optional_base ( in_place_init_t )
0231       :
0232       m_initialized(false), m_storage() {}
0233 
0234     template<class Arg>
0235     explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg&& arg )
0236       :
0237       m_initialized(false)
0238     {
0239       if ( cond )
0240         construct(in_place_init, boost::forward<Arg>(arg));
0241     }
0242 
0243     explicit tc_optional_base ( in_place_init_if_t, bool cond )
0244       :
0245       m_initialized(false)
0246     {
0247       if ( cond )
0248         construct(in_place_init);
0249     }
0250 
0251 #else
0252 
0253     template<class Arg>
0254     void construct ( in_place_init_t, const Arg& arg )
0255      {
0256        m_storage = value_type( arg );
0257        m_initialized = true ;
0258      }
0259 
0260     template<class Arg>
0261     void construct ( in_place_init_t, Arg& arg )
0262      {
0263        m_storage = value_type( arg );
0264        m_initialized = true ;
0265      }
0266 
0267     void construct ( in_place_init_t )
0268      {
0269        m_storage = value_type();
0270        m_initialized = true ;
0271      }
0272 
0273     template<class Arg>
0274     void emplace_assign ( const Arg& arg )
0275     {
0276       construct(in_place_init, arg);
0277     }
0278 
0279     template<class Arg>
0280     void emplace_assign ( Arg& arg )
0281     {
0282       construct(in_place_init, arg);
0283     }
0284 
0285     void emplace_assign ()
0286     {
0287       construct(in_place_init);
0288     }
0289 
0290     template<class Arg>
0291     explicit tc_optional_base ( in_place_init_t, const Arg& arg )
0292       : m_initialized(false)
0293     {
0294       construct(in_place_init, arg);
0295     }
0296 
0297     template<class Arg>
0298     explicit tc_optional_base ( in_place_init_t, Arg& arg )
0299       : m_initialized(false)
0300     {
0301       construct(in_place_init, arg);
0302     }
0303 
0304     explicit tc_optional_base ( in_place_init_t )
0305       : m_initialized(false)
0306     {
0307       construct(in_place_init);
0308     }
0309 
0310     template<class Arg>
0311     explicit tc_optional_base ( in_place_init_if_t, bool cond, const Arg& arg )
0312       : m_initialized(false)
0313     {
0314       if ( cond )
0315         construct(in_place_init, arg);
0316     }
0317 
0318     template<class Arg>
0319     explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg& arg )
0320       : m_initialized(false)
0321     {
0322       if ( cond )
0323         construct(in_place_init, arg);
0324     }
0325 
0326     explicit tc_optional_base ( in_place_init_if_t, bool cond )
0327       : m_initialized(false)
0328     {
0329       if ( cond )
0330         construct(in_place_init);
0331     }
0332 #endif
0333 
0334 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0335 
0336 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0337     // Constructs in-place using the given factory
0338     template<class Expr>
0339     void construct ( Expr&& factory, in_place_factory_base const* )
0340      {
0341        boost_optional_detail::construct<value_type>(factory, boost::addressof(m_storage));
0342        m_initialized = true ;
0343      }
0344 
0345     // Constructs in-place using the given typed factory
0346     template<class Expr>
0347     void construct ( Expr&& factory, typed_in_place_factory_base const* )
0348      {
0349        factory.apply(boost::addressof(m_storage)) ;
0350        m_initialized = true ;
0351      }
0352 
0353     template<class Expr>
0354     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
0355      {
0356        destroy();
0357        construct(factory,tag);
0358      }
0359 
0360     // Constructs in-place using the given typed factory
0361     template<class Expr>
0362     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
0363      {
0364        destroy();
0365        construct(factory,tag);
0366      }
0367 
0368 #else
0369     // Constructs in-place using the given factory
0370     template<class Expr>
0371     void construct ( Expr const& factory, in_place_factory_base const* )
0372      {
0373        boost_optional_detail::construct<value_type>(factory, boost::addressof(m_storage));
0374        m_initialized = true ;
0375      }
0376 
0377     // Constructs in-place using the given typed factory
0378     template<class Expr>
0379     void construct ( Expr const& factory, typed_in_place_factory_base const* )
0380      {
0381        factory.apply(boost::addressof(m_storage)) ;
0382        m_initialized = true ;
0383      }
0384 
0385     template<class Expr>
0386     void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
0387      {
0388        destroy();
0389        construct(factory,tag);
0390      }
0391 
0392     // Constructs in-place using the given typed factory
0393     template<class Expr>
0394     void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
0395      {
0396        destroy();
0397        construct(factory,tag);
0398      }
0399 #endif
0400 
0401 #endif
0402 
0403 #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0404     // Constructs using any expression implicitly convertible to the single argument
0405     // of a one-argument T constructor.
0406     // Converting constructions of optional<T> from optional<U> uses this function with
0407     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
0408     template<class Expr>
0409     void construct ( Expr&& expr, void const* )
0410     {
0411       m_storage = value_type(boost::forward<Expr>(expr)) ;
0412       m_initialized = true ;
0413     }
0414 
0415     // Assigns using a form any expression implicitly convertible to the single argument
0416     // of a T's assignment operator.
0417     // Converting assignments of optional<T> from optional<U> uses this function with
0418     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
0419     template<class Expr>
0420     void assign_expr_to_initialized ( Expr&& expr, void const* )
0421     {
0422       assign_value( boost::forward<Expr>(expr) );
0423     }
0424 #else
0425     // Constructs using any expression implicitly convertible to the single argument
0426     // of a one-argument T constructor.
0427     // Converting constructions of optional<T> from optional<U> uses this function with
0428     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
0429     template<class Expr>
0430     void construct ( Expr const& expr, void const* )
0431      {
0432        m_storage = value_type(expr) ;
0433        m_initialized = true ;
0434      }
0435 
0436     // Assigns using a form any expression implicitly convertible to the single argument
0437     // of a T's assignment operator.
0438     // Converting assignments of optional<T> from optional<U> uses this function with
0439     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
0440     template<class Expr>
0441     void assign_expr_to_initialized ( Expr const& expr, void const* )
0442      {
0443        assign_value(expr);
0444      }
0445 
0446 #endif
0447 
0448 #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0449     // BCB5.64 (and probably lower versions) workaround.
0450     //   The in-place factories are supported by means of catch-all constructors
0451     //   and assignment operators (the functions are parameterized in terms of
0452     //   an arbitrary 'Expr' type)
0453     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
0454     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
0455     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
0456     //   is another optional.
0457     //
0458     // For VC<=70 compilers this workaround doesn't work because the compiler issues and error
0459     // instead of choosing the wrong overload
0460     //
0461 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0462     // Notice that 'Expr' will be optional<T> or optional<U> (but not tc_optional_base<..>)
0463     template<class Expr>
0464     void construct ( Expr&& expr, optional_tag const* )
0465      {
0466        if ( expr.is_initialized() )
0467        {
0468          // An exception can be thrown here.
0469          // It it happens, THIS will be left uninitialized.
0470          m_storage = value_type(boost::move(expr.get())) ;
0471          m_initialized = true ;
0472        }
0473      }
0474 #else
0475     // Notice that 'Expr' will be optional<T> or optional<U> (but not tc_optional_base<..>)
0476     template<class Expr>
0477     void construct ( Expr const& expr, optional_tag const* )
0478      {
0479        if ( expr.is_initialized() )
0480        {
0481          // An exception can be thrown here.
0482          // It it happens, THIS will be left uninitialized.
0483          m_storage = value_type(expr.get()) ;
0484          m_initialized = true ;
0485        }
0486      }
0487 #endif
0488 #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0489 
0490     void assign_value ( argument_type val ) { m_storage = val; }
0491 #ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
0492     void assign_value ( rval_reference_type val ) { m_storage = static_cast<rval_reference_type>(val); }
0493 #endif
0494 
0495     void destroy()
0496     {
0497       m_initialized = false;
0498     }
0499 
0500     reference_const_type get_impl() const { return m_storage ; }
0501     reference_type       get_impl()       { return m_storage ; }
0502 
0503     pointer_const_type get_ptr_impl() const { return boost::addressof(m_storage); }
0504     pointer_type       get_ptr_impl()       { return boost::addressof(m_storage); }
0505 
0506   private :
0507 
0508     bool m_initialized ;
0509     T    m_storage ;
0510 } ;