Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:53:34

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     typedef T &&  rval_reference_type ;
0029     typedef T &&  reference_type_of_temporary_wrapper ;
0030     typedef T *         pointer_type ;
0031     typedef T const*    pointer_const_type ;
0032     typedef T const&    argument_type ;
0033 
0034     tc_optional_base()
0035       :
0036       m_initialized(false), m_storage() {}
0037 
0038     tc_optional_base ( none_t )
0039       :
0040       m_initialized(false), m_storage() {}
0041 
0042     tc_optional_base ( init_value_tag, argument_type val )
0043       :
0044       m_initialized(true), m_storage(val) {}
0045 
0046     tc_optional_base ( bool cond, argument_type val )
0047       :
0048       m_initialized(cond), m_storage(val) {}
0049 
0050     // tc_optional_base ( tc_optional_base const& ) = default;
0051 
0052     template<class Expr, class PtrExpr>
0053     explicit tc_optional_base ( Expr&& expr, PtrExpr const* tag )
0054       :
0055       m_initialized(false)
0056     {
0057       construct(optional_detail::forward<Expr>(expr),tag);
0058     }
0059 
0060     // tc_optional_base& operator= ( tc_optional_base const& ) = default;
0061     // ~tc_optional_base() = default;
0062 
0063     // Assigns from another optional<T> (deep-copies the rhs value)
0064     void assign ( tc_optional_base const& rhs )
0065     {
0066       *this = rhs;
0067     }
0068 
0069     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
0070     template<class U>
0071     void assign ( optional<U> const& rhs )
0072     {
0073       if ( rhs.is_initialized() )
0074 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0075         m_storage = rhs.get();
0076 #else
0077         m_storage = static_cast<value_type>(rhs.get());
0078 #endif
0079 
0080       m_initialized = rhs.is_initialized();
0081     }
0082 
0083     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
0084     template<class U>
0085     void assign ( optional<U>&& rhs )
0086     {
0087       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
0088       if ( rhs.is_initialized() )
0089         m_storage = static_cast<ref_type>(rhs.get());
0090       m_initialized = rhs.is_initialized();
0091     }
0092 
0093     void assign ( argument_type val )
0094     {
0095       construct(val);
0096     }
0097 
0098     void assign ( none_t ) { destroy(); }
0099 
0100 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0101 
0102     template<class Expr, class ExprPtr>
0103     void assign_expr ( Expr&& expr, ExprPtr const* tag )
0104     {
0105        construct(optional_detail::forward<Expr>(expr),tag);
0106     }
0107 
0108 #endif
0109 
0110   public :
0111 
0112     // Destroys the current value, if any, leaving this UNINITIALIZED
0113     // No-throw (assuming T::~T() doesn't)
0114     void reset() BOOST_NOEXCEPT { destroy(); }
0115 
0116     // **DEPRECATED** Replaces the current value -if any- with 'val'
0117     void reset ( argument_type val ) BOOST_NOEXCEPT { assign(val); }
0118 
0119     // Returns a pointer to the value if this is initialized, otherwise,
0120     // returns NULL.
0121     // No-throw
0122     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
0123     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
0124 
0125     bool is_initialized() const { return m_initialized ; }
0126 
0127   protected :
0128 
0129     void construct ( argument_type val )
0130      {
0131        m_storage = val ;
0132        m_initialized = true ;
0133      }
0134 
0135 
0136     // Constructs in-place
0137     // upon exception *this is always uninitialized
0138     template<class... Args>
0139     void construct ( in_place_init_t, Args&&... args )
0140     {
0141       m_storage = value_type( optional_detail::forward<Args>(args)... ) ;
0142       m_initialized = true ;
0143     }
0144 
0145     template<class... Args>
0146     void emplace_assign ( Args&&... args )
0147     {
0148       construct(in_place_init, optional_detail::forward<Args>(args)...);
0149     }
0150 
0151     template<class... Args>
0152     explicit tc_optional_base ( in_place_init_t, Args&&... args )
0153       :
0154       m_initialized(false)
0155     {
0156       construct(in_place_init, optional_detail::forward<Args>(args)...);
0157     }
0158 
0159     template<class... Args>
0160     explicit tc_optional_base ( in_place_init_if_t, bool cond, Args&&... args )
0161       :
0162       m_initialized(false)
0163     {
0164       if ( cond )
0165         construct(in_place_init, optional_detail::forward<Args>(args)...);
0166     }
0167 
0168 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0169 
0170     // Constructs in-place using the given factory
0171     template<class Expr>
0172     void construct ( Expr&& factory, in_place_factory_base const* )
0173      {
0174        boost_optional_detail::construct<value_type>(factory, boost::addressof(m_storage));
0175        m_initialized = true ;
0176      }
0177 
0178     // Constructs in-place using the given typed factory
0179     template<class Expr>
0180     void construct ( Expr&& factory, typed_in_place_factory_base const* )
0181      {
0182        factory.apply(boost::addressof(m_storage)) ;
0183        m_initialized = true ;
0184      }
0185 
0186     template<class Expr>
0187     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
0188      {
0189        destroy();
0190        construct(factory,tag);
0191      }
0192 
0193     // Constructs in-place using the given typed factory
0194     template<class Expr>
0195     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
0196      {
0197        destroy();
0198        construct(factory,tag);
0199      }
0200 
0201 #endif
0202 
0203     // Constructs using any expression implicitly convertible to the single argument
0204     // of a one-argument T constructor.
0205     // Converting constructions of optional<T> from optional<U> uses this function with
0206     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
0207     template<class Expr>
0208     void construct ( Expr&& expr, void const* )
0209     {
0210       m_storage = value_type(optional_detail::forward<Expr>(expr)) ;
0211       m_initialized = true ;
0212     }
0213 
0214     // Assigns using a form any expression implicitly convertible to the single argument
0215     // of a T's assignment operator.
0216     // Converting assignments of optional<T> from optional<U> uses this function with
0217     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
0218     template<class Expr>
0219     void assign_expr_to_initialized ( Expr&& expr, void const* )
0220     {
0221       assign_value( optional_detail::forward<Expr>(expr) );
0222     }
0223 
0224 #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0225     // BCB5.64 (and probably lower versions) workaround.
0226     //   The in-place factories are supported by means of catch-all constructors
0227     //   and assignment operators (the functions are parameterized in terms of
0228     //   an arbitrary 'Expr' type)
0229     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
0230     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
0231     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
0232     //   is another optional.
0233     //
0234     // For VC<=70 compilers this workaround doesn't work because the compiler issues and error
0235     // instead of choosing the wrong overload
0236     //
0237 
0238     // Notice that 'Expr' will be optional<T> or optional<U> (but not tc_optional_base<..>)
0239     template<class Expr>
0240     void construct ( Expr&& expr, optional_tag const* )
0241      {
0242        if ( expr.is_initialized() )
0243        {
0244          // An exception can be thrown here.
0245          // It it happens, THIS will be left uninitialized.
0246          m_storage = value_type(optional_detail::move(expr.get())) ;
0247          m_initialized = true ;
0248        }
0249      }
0250 #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0251 
0252     void assign_value ( argument_type val ) { m_storage = val; }
0253     void assign_value ( rval_reference_type val ) { m_storage = static_cast<rval_reference_type>(val); }
0254 
0255     void destroy()
0256     {
0257       m_initialized = false;
0258     }
0259 
0260     reference_const_type get_impl() const { return m_storage ; }
0261     reference_type       get_impl()       { return m_storage ; }
0262 
0263     pointer_const_type get_ptr_impl() const { return boost::addressof(m_storage); }
0264     pointer_type       get_ptr_impl()       { return boost::addressof(m_storage); }
0265 
0266   private :
0267 
0268     bool m_initialized ;
0269     T    m_storage ;
0270 } ;