common.h
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
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   // Transparent. Forward `K`.
00036   template <typename K, typename key_type>
00037   using type = K;
00038 };
00039 
00040 template <>
00041 struct KeyArg<false> {
00042   // Not transparent. Always use `key_type`.
00043   template <typename K, typename key_type>
00044   using type = key_type;
00045 };
00046 
00047 // The node_handle concept from C++17.
00048 // We specialize node_handle for sets and maps. node_handle_base holds the
00049 // common API of both.
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 // For sets.
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 // For maps.
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 // Provide access to non-public node-handle functions.
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 // Implement the insert_return_type<> concept of C++17.
00173 template <class Iterator, class NodeType>
00174 struct InsertReturnType {
00175   Iterator position;
00176   bool inserted;
00177   NodeType node;
00178 };
00179 
00180 }  // namespace container_internal
00181 }  // namespace absl
00182 
00183 #endif  // ABSL_CONTAINER_INTERNAL_CONTAINER_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14