cycle_ptr
allocator.h
1 #ifndef CYCLE_PTR_ALLOCATOR_H
2 #define CYCLE_PTR_ALLOCATOR_H
3 
4 #include <memory>
5 #include <functional>
6 #include <utility>
7 #include <type_traits>
8 #include <cycle_ptr/detail/base_control.h>
9 
10 namespace cycle_ptr {
11 
12 
18 template<typename Nested>
20 : public Nested
21 {
22  template<typename> friend class cycle_allocator;
23 
24  public:
26  using propagate_on_container_copy_assignment = std::false_type;
28  using propagate_on_container_move_assignment = std::false_type;
30  using propagate_on_container_swap = std::false_type;
32  using is_always_equal = std::false_type;
33 
35  template<typename T>
36  struct rebind {
39  };
40 
42  template<typename Other>
44  noexcept(std::is_nothrow_constructible_v<Nested, const Other&>)
45  : Nested(other),
46  control_(other.control_)
47  {}
48 
52  template<typename... Args, typename = std::enable_if_t<std::is_constructible_v<Nested, Args...>>>
53  explicit cycle_allocator(const cycle_base& base, Args&&... args)
54  : Nested(std::forward<Args>(args)...),
55  control_(base.control_)
56  {}
57 
61  template<typename... Args, typename = std::enable_if_t<std::is_constructible_v<Nested, Args...>>>
62  explicit cycle_allocator([[maybe_unused]] unowned_cycle_t unowned_tag, Args&&... args)
63  : Nested(std::forward<Args>(args)...),
64  control_(detail::base_control::unowned_control())
65  {}
66 
76  template<typename T, typename... Args>
77  auto construct(T* ptr, Args&&... args)
78  -> void {
79  detail::base_control::publisher pub{ ptr, sizeof(T), *control_ };
80  std::allocator_traits<Nested>::construct(*this, ptr, std::forward<Args>(args)...);
81  }
82 
93  template<typename Dummy = void>
95  -> cycle_allocator {
96  static_assert(std::is_void_v<Dummy> && false,
97  "You must explicitly specify an allocator with owner during copy.");
98  return *this;
99  }
100 
109  auto operator==(const cycle_allocator& other) const
110  noexcept(
111  std::allocator_traits<Nested>::is_always_equal::value
112  || noexcept(std::declval<const Nested&>() == std::declval<const Nested&>()))
113  -> bool {
114  if constexpr(!std::allocator_traits<Nested>::is_always_equal::value) {
115  if (!std::equal_to<Nested>()(*this, other)) return false;
116  }
117 
118  return control_ == other.control_
119  || (control_->is_unowned() && other.control_->is_unowned());
120  }
121 
123  auto operator!=(const cycle_allocator& other) const
124  noexcept(noexcept(*this == other))
125  -> bool {
126  return !(*this == other);
127  }
128 
129  private:
132 };
133 
134 
135 } /* namespace cycle_ptr */
136 
137 #endif /* CYCLE_PTR_ALLOCATOR_H */
auto select_on_container_copy_construction() -> cycle_allocator
Fail to create copy of this allocator.
Definition: allocator.h:94
Adaptor for collections with member types.
Definition: allocator.h:19
cycle_allocator(const cycle_base &base, Args &&... args)
Create allocator, with declared ownership.
Definition: allocator.h:53
std::false_type propagate_on_container_move_assignment
When move-assigning, allocator is not copied over.
Definition: allocator.h:28
Address range publisher.
Definition: base_control.h:215
Intrusive pointer.
Definition: intrusive_ptr.h:21
cycle_allocator([[maybe_unused]] unowned_cycle_t unowned_tag, Args &&... args)
Create allocator, with elements having no ownership.
Definition: allocator.h:62
std::false_type propagate_on_container_swap
When performing swap, allocator is not swapped.
Definition: allocator.h:30
cycle_allocator(const cycle_allocator< Other > &other) noexcept(std::is_nothrow_constructible_v< Nested, const Other & >)
Copy constructor for distinct type.
Definition: allocator.h:43
std::false_type is_always_equal
Must check for equality.
Definition: allocator.h:32
Tag indicating an edge without owner.
Definition: cycle_ptr.h:24
auto construct(T *ptr, Args &&... args) -> void
Constructor.
Definition: allocator.h:77
auto operator==(const cycle_allocator &other) const noexcept(std::allocator_traits< Nested >::is_always_equal::value||noexcept(std::declval< const Nested & >()==std::declval< const Nested & >())) -> bool
Compare allocators for equality.
Definition: allocator.h:109
An optional base for classes which need to supply ownership to cycle_member_ptr.
Definition: cycle_ptr.h:49
std::false_type propagate_on_container_copy_assignment
When copy-assigning, allocator is not copied over.
Definition: allocator.h:26
auto operator!=(const cycle_allocator &other) const noexcept(noexcept(*this==other)) -> bool
Inequality comparison.
Definition: allocator.h:123
Template for changing controlled type of allocator.
Definition: allocator.h:36