File indexing completed on 2025-01-18 09:53:19
0001
0002
0003
0004
0005
0006
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()){
0112
0113 }else{
0114 emplace(std::move(nh.p_),std::move(nh.al()));
0115 nh.reset();
0116 }
0117 }else{
0118 if(nh.empty()){
0119 type_policy::destroy(al(),&p_);
0120 reset();
0121 }else{
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()){
0139
0140 }else{
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
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