Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:19

0001 /* Copyright 2023 Christian Mazakas.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See https://www.boost.org/libs/unordered for library home page.
0007  */
0008 
0009 #ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
0010 #define BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
0011 
0012 #include <boost/unordered/detail/opt_storage.hpp>
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/core/allocator_access.hpp>
0016 
0017 namespace boost{
0018 namespace unordered{
0019 namespace detail{
0020 namespace foa{
0021 
0022 template <class Iterator,class NodeType>
0023 struct insert_return_type
0024 {
0025   Iterator position;
0026   bool     inserted;
0027   NodeType node;
0028 };
0029 
0030 template <class TypePolicy,class Allocator>
0031 struct node_handle_base
0032 {
0033   protected:
0034     using type_policy=TypePolicy;
0035     using element_type=typename type_policy::element_type;
0036 
0037   public:
0038     using allocator_type = Allocator;
0039 
0040   private:
0041     using node_value_type=typename type_policy::value_type;
0042     element_type p_;
0043     BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS opt_storage<Allocator> a_;
0044 
0045   protected:
0046     node_value_type& data()noexcept
0047     {
0048       return *(p_.p);
0049     }
0050 
0051     node_value_type const& data()const noexcept
0052     {
0053       return *(p_.p);
0054     }
0055 
0056     element_type& element()noexcept
0057     {
0058       BOOST_ASSERT(!empty());
0059       return p_;
0060     }
0061 
0062     element_type const& element()const noexcept
0063     {
0064       BOOST_ASSERT(!empty());
0065       return p_;
0066     }
0067 
0068     Allocator& al()noexcept
0069     {
0070       BOOST_ASSERT(!empty());
0071       return a_.t_;
0072     }
0073 
0074     Allocator const& al()const noexcept
0075     {
0076       BOOST_ASSERT(!empty());
0077       return a_.t_;
0078     }
0079 
0080     void emplace(element_type&& x,Allocator a)
0081     {
0082       BOOST_ASSERT(empty());
0083       auto* p=x.p;
0084       p_.p=p;
0085       new(&a_.t_)Allocator(a);
0086       x.p=nullptr;
0087     }
0088 
0089     void reset()
0090     {
0091       a_.t_.~Allocator();
0092       p_.p=nullptr;
0093     }
0094 
0095   public:
0096     constexpr node_handle_base()noexcept:p_{nullptr}{}
0097 
0098     node_handle_base(node_handle_base&& nh) noexcept
0099     {
0100       p_.p = nullptr;
0101       if (!nh.empty()){
0102         emplace(std::move(nh.p_),nh.al());
0103         nh.reset();
0104       }
0105     }
0106 
0107     node_handle_base& operator=(node_handle_base&& nh)noexcept
0108     {
0109       if(this!=&nh){
0110         if(empty()){
0111           if(nh.empty()){                      /* empty(),  nh.empty() */
0112             /* nothing to do */
0113           }else{                               /* empty(), !nh.empty() */
0114             emplace(std::move(nh.p_),std::move(nh.al()));
0115             nh.reset();
0116           }
0117         }else{
0118           if(nh.empty()){                      /* !empty(),  nh.empty() */
0119             type_policy::destroy(al(),&p_);
0120             reset();
0121           }else{                               /* !empty(), !nh.empty() */
0122             bool const pocma=
0123               boost::allocator_propagate_on_container_move_assignment<
0124                 Allocator>::type::value;
0125 
0126             BOOST_ASSERT(pocma||al()==nh.al());
0127 
0128             type_policy::destroy(al(),&p_);
0129             if(pocma){
0130               al()=std::move(nh.al());
0131             }
0132 
0133             p_=std::move(nh.p_);
0134             nh.reset();
0135           }
0136         }
0137       }else{
0138         if(empty()){                           /* empty(),  nh.empty() */
0139           /* nothing to do */
0140         }else{                                 /* !empty(), !nh.empty() */
0141           type_policy::destroy(al(),&p_);
0142           reset();
0143         }
0144       }
0145       return *this;
0146     }
0147 
0148     ~node_handle_base()
0149     {
0150       if(!empty()){
0151         type_policy::destroy(al(),&p_);
0152         reset();
0153       }
0154     }
0155 
0156     allocator_type get_allocator()const noexcept{return al();}
0157     explicit operator bool()const noexcept{ return !empty();}
0158     BOOST_ATTRIBUTE_NODISCARD bool empty()const noexcept{return p_.p==nullptr;}
0159 
0160     void swap(node_handle_base& nh) noexcept(
0161       boost::allocator_is_always_equal<Allocator>::type::value||
0162       boost::allocator_propagate_on_container_swap<Allocator>::type::value)
0163     {
0164       if(this!=&nh){
0165         if(empty()){
0166           if(nh.empty()) {
0167             /* nothing to do here */
0168           } else {
0169             emplace(std::move(nh.p_), nh.al());
0170             nh.reset();
0171           }
0172         }else{
0173           if(nh.empty()){
0174             nh.emplace(std::move(p_),al());
0175             reset();
0176           }else{
0177             bool const pocs=
0178               boost::allocator_propagate_on_container_swap<
0179                 Allocator>::type::value;
0180 
0181             BOOST_ASSERT(pocs || al()==nh.al());
0182 
0183             using std::swap;
0184             p_.swap(nh.p_);
0185             if(pocs)swap(al(),nh.al());
0186           }
0187         }
0188       }
0189     }
0190 
0191     friend
0192     void swap(node_handle_base& lhs,node_handle_base& rhs)
0193       noexcept(noexcept(lhs.swap(rhs)))
0194     {
0195       return lhs.swap(rhs);
0196     }
0197 };
0198 
0199 }
0200 }
0201 }
0202 }
0203 
0204 #endif // BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP