Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_H_
00016 #define ABSL_CONTAINER_INTERNAL_CONTAINER_H_
00017
00018 #include <cassert>
00019 #include <type_traits>
00020
00021 #include "absl/meta/type_traits.h"
00022 #include "absl/types/optional.h"
00023
00024 namespace absl {
00025 namespace container_internal {
00026
00027 template <class, class = void>
00028 struct IsTransparent : std::false_type {};
00029 template <class T>
00030 struct IsTransparent<T, absl::void_t<typename T::is_transparent>>
00031 : std::true_type {};
00032
00033 template <bool is_transparent>
00034 struct KeyArg {
00035
00036 template <typename K, typename key_type>
00037 using type = K;
00038 };
00039
00040 template <>
00041 struct KeyArg<false> {
00042
00043 template <typename K, typename key_type>
00044 using type = key_type;
00045 };
00046
00047
00048
00049
00050 template <typename PolicyTraits, typename Alloc>
00051 class node_handle_base {
00052 protected:
00053 using slot_type = typename PolicyTraits::slot_type;
00054
00055 public:
00056 using allocator_type = Alloc;
00057
00058 constexpr node_handle_base() {}
00059 node_handle_base(node_handle_base&& other) noexcept {
00060 *this = std::move(other);
00061 }
00062 ~node_handle_base() { destroy(); }
00063 node_handle_base& operator=(node_handle_base&& other) noexcept {
00064 destroy();
00065 if (!other.empty()) {
00066 alloc_ = other.alloc_;
00067 PolicyTraits::transfer(alloc(), slot(), other.slot());
00068 other.reset();
00069 }
00070 return *this;
00071 }
00072
00073 bool empty() const noexcept { return !alloc_; }
00074 explicit operator bool() const noexcept { return !empty(); }
00075 allocator_type get_allocator() const { return *alloc_; }
00076
00077 protected:
00078 friend struct CommonAccess;
00079
00080 node_handle_base(const allocator_type& a, slot_type* s) : alloc_(a) {
00081 PolicyTraits::transfer(alloc(), slot(), s);
00082 }
00083
00084 void destroy() {
00085 if (!empty()) {
00086 PolicyTraits::destroy(alloc(), slot());
00087 reset();
00088 }
00089 }
00090
00091 void reset() {
00092 assert(alloc_.has_value());
00093 alloc_ = absl::nullopt;
00094 }
00095
00096 slot_type* slot() const {
00097 assert(!empty());
00098 return reinterpret_cast<slot_type*>(std::addressof(slot_space_));
00099 }
00100 allocator_type* alloc() { return std::addressof(*alloc_); }
00101
00102 private:
00103 absl::optional<allocator_type> alloc_;
00104 mutable absl::aligned_storage_t<sizeof(slot_type), alignof(slot_type)>
00105 slot_space_;
00106 };
00107
00108
00109 template <typename Policy, typename PolicyTraits, typename Alloc,
00110 typename = void>
00111 class node_handle : public node_handle_base<PolicyTraits, Alloc> {
00112 using Base = typename node_handle::node_handle_base;
00113
00114 public:
00115 using value_type = typename PolicyTraits::value_type;
00116
00117 constexpr node_handle() {}
00118
00119 value_type& value() const { return PolicyTraits::element(this->slot()); }
00120
00121 private:
00122 friend struct CommonAccess;
00123
00124 node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {}
00125 };
00126
00127
00128 template <typename Policy, typename PolicyTraits, typename Alloc>
00129 class node_handle<Policy, PolicyTraits, Alloc,
00130 absl::void_t<typename Policy::mapped_type>>
00131 : public node_handle_base<PolicyTraits, Alloc> {
00132 using Base = typename node_handle::node_handle_base;
00133
00134 public:
00135 using key_type = typename Policy::key_type;
00136 using mapped_type = typename Policy::mapped_type;
00137
00138 constexpr node_handle() {}
00139
00140 auto key() const -> decltype(PolicyTraits::key(this->slot())) {
00141 return PolicyTraits::key(this->slot());
00142 }
00143
00144 mapped_type& mapped() const {
00145 return PolicyTraits::value(&PolicyTraits::element(this->slot()));
00146 }
00147
00148 private:
00149 friend struct CommonAccess;
00150
00151 node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {}
00152 };
00153
00154
00155 struct CommonAccess {
00156 template <typename Node>
00157 static auto GetSlot(const Node& node) -> decltype(node.slot()) {
00158 return node.slot();
00159 }
00160
00161 template <typename Node>
00162 static void Reset(Node* node) {
00163 node->reset();
00164 }
00165
00166 template <typename T, typename... Args>
00167 static T Make(Args&&... args) {
00168 return T(std::forward<Args>(args)...);
00169 }
00170 };
00171
00172
00173 template <class Iterator, class NodeType>
00174 struct InsertReturnType {
00175 Iterator position;
00176 bool inserted;
00177 NodeType node;
00178 };
00179
00180 }
00181 }
00182
00183 #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_