Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:11

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Benedek Thaler 2015-2016
0004 // (C) Copyright Ion Gaztanaga 2019-2020. Distributed under the Boost
0005 // Software License, Version 1.0. (See accompanying file
0006 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://erenon.hu/container for documentation.
0009 //
0010 //////////////////////////////////////////////////////////////////////////////
0011 
0012 #ifndef BOOST_CONTAINER_DETAIL_GUARDS_HPP
0013 #define BOOST_CONTAINER_DETAIL_GUARDS_HPP
0014 
0015 #include <boost/container/detail/config_begin.hpp>
0016 #include <boost/container/detail/workaround.hpp>
0017 
0018 #include <boost/move/core.hpp> // BOOST_MOVABLE_BUT_NOT_COPYABLE
0019 
0020 // move/detail
0021 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0022 #include <boost/move/detail/fwd_macros.hpp>
0023 #endif
0024 
0025 #include <boost/container/allocator_traits.hpp>
0026 
0027 namespace boost {
0028 namespace container {
0029 namespace detail {
0030 
0031 class null_construction_guard
0032 {
0033 public:
0034 
0035    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0036 
0037    template <typename... Args>
0038    null_construction_guard(Args&&...) {}
0039 
0040    #else
0041 
0042    #define NULL_CONSTRUCTION_GUARD_CODE(N) \
0043    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0044    BOOST_CONTAINER_FORCEINLINE null_construction_guard(BOOST_MOVE_UREFANON##N)\
0045    {}\
0046    //
0047    BOOST_MOVE_ITERATE_0TO9(NULL_CONSTRUCTION_GUARD_CODE)
0048    #undef NULL_CONSTRUCTION_GUARD_CODE
0049    #endif
0050 
0051    void release() {}
0052    void extend() {}
0053 };
0054 
0055 template <typename Allocator>
0056 class construction_guard
0057 {
0058   typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0059   typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0060 
0061   BOOST_MOVABLE_BUT_NOT_COPYABLE(construction_guard)
0062 
0063 public:
0064    construction_guard()
0065       : _alloc_ptr()
0066       , _elem_count()
0067       , _allocator()
0068    {}
0069 
0070   construction_guard(pointer alloc_ptr, Allocator& allocator)
0071       :_alloc_ptr(alloc_ptr)
0072       , _elem_count(0)
0073       , _allocator(&allocator)
0074   {}
0075 
0076   construction_guard(BOOST_RV_REF(construction_guard) rhs)
0077       :_alloc_ptr(rhs._alloc_ptr)
0078       , _elem_count(rhs._elem_count)
0079       , _allocator(rhs._allocator)
0080   {
0081     rhs._elem_count = 0;
0082   }
0083 
0084   ~construction_guard()
0085   {
0086     while (_elem_count) {
0087       --_elem_count;
0088       boost::container::allocator_traits<Allocator>::destroy(*_allocator, _alloc_ptr++);
0089     }
0090   }
0091 
0092   void release()
0093   {
0094     _elem_count = 0;
0095   }
0096 
0097   void extend()
0098   {
0099     ++_elem_count;
0100   }
0101 
0102 private:
0103   pointer _alloc_ptr;
0104   size_type _elem_count;
0105   Allocator* _allocator;
0106 };
0107 
0108 
0109 /**
0110  * Has two ranges
0111  *
0112  * On success, destroys the first range (src),
0113  * on failure, destroys the second range (dst).
0114  *
0115  * Can be used when copying/moving a range
0116  */
0117 template <class Allocator>
0118 class nand_construction_guard
0119 {
0120    typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0121    typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0122 
0123    construction_guard<Allocator> _src;
0124    construction_guard<Allocator> _dst;
0125    bool _dst_released;
0126 
0127    public:
0128    nand_construction_guard()
0129       : _src()
0130       , _dst()
0131       , _dst_released(false)
0132    {}
0133 
0134    nand_construction_guard( pointer src, Allocator& src_alloc
0135                           , pointer dst, Allocator& dst_alloc)
0136     :_src(src, src_alloc),
0137      _dst(dst, dst_alloc),
0138      _dst_released(false)
0139    {}
0140 
0141    void extend()
0142    {
0143       _src.extend();
0144       _dst.extend();
0145    }
0146 
0147    void release() // on success
0148    {
0149       _dst.release();
0150       _dst_released = true;
0151    }
0152 
0153    ~nand_construction_guard()
0154    {
0155       if (! _dst_released) { _src.release(); }
0156    }
0157 };
0158 
0159 
0160 template <typename Allocator>
0161 class allocation_guard
0162 {
0163   typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
0164   typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
0165 
0166   BOOST_MOVABLE_BUT_NOT_COPYABLE(allocation_guard)
0167 
0168 public:
0169   allocation_guard(pointer alloc_ptr, size_type alloc_size, Allocator& allocator)
0170     :_alloc_ptr(alloc_ptr),
0171      _alloc_size(alloc_size),
0172      _allocator(allocator)
0173   {}
0174 
0175   ~allocation_guard()
0176   {
0177     if (_alloc_ptr)
0178     {
0179       boost::container::allocator_traits<Allocator>::deallocate(_allocator, _alloc_ptr, _alloc_size);
0180     }
0181   }
0182 
0183   void release()
0184   {
0185     _alloc_ptr = 0;
0186   }
0187 
0188 private:
0189   pointer _alloc_ptr;
0190   size_type _alloc_size;
0191   Allocator& _allocator;
0192 };
0193 
0194 }}} // namespace boost::container::detail
0195 
0196 #include <boost/container/detail/config_end.hpp>
0197 
0198 #endif // BOOST_CONTAINER_DETAIL_GUARDS_HPP