LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/optional/detail - optional_trivially_copyable_base.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 15 16 93.8 %
Date: 2026-06-25 07:23:43 Functions: 8 10 80.0 %

          Line data    Source code
       1             : // Copyright (C) 2017 Andrzej Krzemienski.
       2             : //
       3             : // Use, modification, and distribution is subject to the Boost Software
       4             : // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       5             : // http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // See http://www.boost.org/libs/optional for documentation.
       8             : //
       9             : // You are welcome to contact the author at:
      10             : //  akrzemi1@gmail.com
      11             : 
      12             : // trivially-copyable version of the storage
      13             : 
      14             : template<class T>
      15             : class tc_optional_base : public optional_tag
      16             : {
      17             :   private :
      18             : 
      19             :     typedef tc_optional_base<T> this_type ;
      20             : 
      21             :   protected :
      22             : 
      23             :     typedef T value_type ;
      24             : 
      25             :   protected:
      26             :     typedef T &       reference_type ;
      27             :     typedef T const&  reference_const_type ;
      28             :     typedef T &&  rval_reference_type ;
      29             :     typedef T &&  reference_type_of_temporary_wrapper ;
      30             :     typedef T *         pointer_type ;
      31             :     typedef T const*    pointer_const_type ;
      32             :     typedef T const&    argument_type ;
      33             : 
      34       60256 :     tc_optional_base()
      35             :       :
      36       60256 :       m_initialized(false), m_storage() {}
      37             : 
      38             :     tc_optional_base ( none_t )
      39             :       :
      40             :       m_initialized(false), m_storage() {}
      41             : 
      42             :     tc_optional_base ( init_value_tag, argument_type val )
      43             :       :
      44             :       m_initialized(true), m_storage(val) {}
      45             : 
      46             :     tc_optional_base ( bool cond, argument_type val )
      47             :       :
      48             :       m_initialized(cond), m_storage(val) {}
      49             : 
      50             :     // tc_optional_base ( tc_optional_base const& ) = default;
      51             : 
      52             :     template<class Expr, class PtrExpr>
      53             :     explicit tc_optional_base ( Expr&& expr, PtrExpr const* tag )
      54             :       :
      55             :       m_initialized(false)
      56             :     {
      57             :       construct(optional_detail::forward<Expr>(expr),tag);
      58             :     }
      59             : 
      60             :     // tc_optional_base& operator= ( tc_optional_base const& ) = default;
      61             :     // ~tc_optional_base() = default;
      62             : 
      63             :     // Assigns from another optional<T> (deep-copies the rhs value)
      64             :     void assign ( tc_optional_base const& rhs )
      65             :     {
      66             :       *this = rhs;
      67             :     }
      68             : 
      69             :     // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
      70             :     template<class U>
      71             :     void assign ( optional<U> const& rhs )
      72             :     {
      73             :       if ( rhs.is_initialized() )
      74             : #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
      75             :         m_storage = rhs.get();
      76             : #else
      77             :         m_storage = static_cast<value_type>(rhs.get());
      78             : #endif
      79             : 
      80             :       m_initialized = rhs.is_initialized();
      81             :     }
      82             : 
      83             :     // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
      84             :     template<class U>
      85             :     void assign ( optional<U>&& rhs )
      86             :     {
      87             :       typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
      88             :       if ( rhs.is_initialized() )
      89             :         m_storage = static_cast<ref_type>(rhs.get());
      90             :       m_initialized = rhs.is_initialized();
      91             :     }
      92             : 
      93         702 :     void assign ( argument_type val )
      94             :     {
      95         702 :       construct(val);
      96         702 :     }
      97             : 
      98             :     void assign ( none_t ) { destroy(); }
      99             : 
     100             : #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     101             : 
     102             :     template<class Expr, class ExprPtr>
     103             :     void assign_expr ( Expr&& expr, ExprPtr const* tag )
     104             :     {
     105             :        construct(optional_detail::forward<Expr>(expr),tag);
     106             :     }
     107             : 
     108             : #endif
     109             : 
     110             :   public :
     111             : 
     112             :     // Destroys the current value, if any, leaving this UNINITIALIZED
     113             :     // No-throw (assuming T::~T() doesn't)
     114         351 :     void reset() BOOST_NOEXCEPT { destroy(); }
     115             : 
     116             :     // **DEPRECATED** Replaces the current value -if any- with 'val'
     117             :     void reset ( argument_type val ) BOOST_NOEXCEPT { assign(val); }
     118             : 
     119             :     // Returns a pointer to the value if this is initialized, otherwise,
     120             :     // returns NULL.
     121             :     // No-throw
     122             :     pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
     123             :     pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
     124             : 
     125        1404 :     bool is_initialized() const { return m_initialized ; }
     126             : 
     127             :   protected :
     128             : 
     129         702 :     void construct ( argument_type val )
     130             :      {
     131         702 :        m_storage = val ;
     132         702 :        m_initialized = true ;
     133         702 :      }
     134             : 
     135             : 
     136             :     // Constructs in-place
     137             :     // upon exception *this is always uninitialized
     138             :     template<class... Args>
     139             :     void construct ( in_place_init_t, Args&&... args )
     140             :     {
     141             :       m_storage = value_type( optional_detail::forward<Args>(args)... ) ;
     142             :       m_initialized = true ;
     143             :     }
     144             : 
     145             :     template<class... Args>
     146             :     void emplace_assign ( Args&&... args )
     147             :     {
     148             :       construct(in_place_init, optional_detail::forward<Args>(args)...);
     149             :     }
     150             : 
     151             :     template<class... Args>
     152             :     explicit tc_optional_base ( in_place_init_t, Args&&... args )
     153             :       :
     154             :       m_initialized(false)
     155             :     {
     156             :       construct(in_place_init, optional_detail::forward<Args>(args)...);
     157             :     }
     158             : 
     159             :     template<class... Args>
     160             :     explicit tc_optional_base ( in_place_init_if_t, bool cond, Args&&... args )
     161             :       :
     162             :       m_initialized(false)
     163             :     {
     164             :       if ( cond )
     165             :         construct(in_place_init, optional_detail::forward<Args>(args)...);
     166             :     }
     167             : 
     168             : #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
     169             : 
     170             :     // Constructs in-place using the given factory
     171             :     template<class Expr>
     172             :     void construct ( Expr&& factory, in_place_factory_base const* )
     173             :      {
     174             :        boost_optional_detail::construct<value_type>(factory, boost::addressof(m_storage));
     175             :        m_initialized = true ;
     176             :      }
     177             : 
     178             :     // Constructs in-place using the given typed factory
     179             :     template<class Expr>
     180             :     void construct ( Expr&& factory, typed_in_place_factory_base const* )
     181             :      {
     182             :        factory.apply(boost::addressof(m_storage)) ;
     183             :        m_initialized = true ;
     184             :      }
     185             : 
     186             :     template<class Expr>
     187             :     void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
     188             :      {
     189             :        destroy();
     190             :        construct(factory,tag);
     191             :      }
     192             : 
     193             :     // Constructs in-place using the given typed factory
     194             :     template<class Expr>
     195             :     void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
     196             :      {
     197             :        destroy();
     198             :        construct(factory,tag);
     199             :      }
     200             : 
     201             : #endif
     202             : 
     203             :     // Constructs using any expression implicitly convertible to the single argument
     204             :     // of a one-argument T constructor.
     205             :     // Converting constructions of optional<T> from optional<U> uses this function with
     206             :     // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
     207             :     template<class Expr>
     208             :     void construct ( Expr&& expr, void const* )
     209             :     {
     210             :       m_storage = value_type(optional_detail::forward<Expr>(expr)) ;
     211             :       m_initialized = true ;
     212             :     }
     213             : 
     214             :     // Assigns using a form any expression implicitly convertible to the single argument
     215             :     // of a T's assignment operator.
     216             :     // Converting assignments of optional<T> from optional<U> uses this function with
     217             :     // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
     218             :     template<class Expr>
     219             :     void assign_expr_to_initialized ( Expr&& expr, void const* )
     220             :     {
     221             :       assign_value( optional_detail::forward<Expr>(expr) );
     222             :     }
     223             : 
     224             : #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
     225             :     // BCB5.64 (and probably lower versions) workaround.
     226             :     //   The in-place factories are supported by means of catch-all constructors
     227             :     //   and assignment operators (the functions are parameterized in terms of
     228             :     //   an arbitrary 'Expr' type)
     229             :     //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
     230             :     //   to the 'Expr'-taking functions even though explicit overloads are present for them.
     231             :     //   Thus, the following overload is needed to properly handle the case when the 'lhs'
     232             :     //   is another optional.
     233             :     //
     234             :     // For VC<=70 compilers this workaround doesn't work because the compiler issues and error
     235             :     // instead of choosing the wrong overload
     236             :     //
     237             : 
     238             :     // Notice that 'Expr' will be optional<T> or optional<U> (but not tc_optional_base<..>)
     239             :     template<class Expr>
     240             :     void construct ( Expr&& expr, optional_tag const* )
     241             :      {
     242             :        if ( expr.is_initialized() )
     243             :        {
     244             :          // An exception can be thrown here.
     245             :          // It it happens, THIS will be left uninitialized.
     246             :          m_storage = value_type(optional_detail::move(expr.get())) ;
     247             :          m_initialized = true ;
     248             :        }
     249             :      }
     250             : #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
     251             : 
     252             :     void assign_value ( argument_type val ) { m_storage = val; }
     253             :     void assign_value ( rval_reference_type val ) { m_storage = static_cast<rval_reference_type>(val); }
     254             : 
     255         351 :     void destroy()
     256             :     {
     257         351 :       m_initialized = false;
     258         351 :     }
     259             : 
     260           0 :     reference_const_type get_impl() const { return m_storage ; }
     261         702 :     reference_type       get_impl()       { return m_storage ; }
     262             : 
     263             :     pointer_const_type get_ptr_impl() const { return boost::addressof(m_storage); }
     264             :     pointer_type       get_ptr_impl()       { return boost::addressof(m_storage); }
     265             : 
     266             :   private :
     267             : 
     268             :     bool m_initialized ;
     269             :     T    m_storage ;
     270             : } ;

Generated by: LCOV version 1.16