Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

no_capacity.hpp
Go to the documentation of this file.
1 //
2 // immer: immutable data structures for C++
3 // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4 //
5 // This software is distributed under the Boost Software License, Version 1.0.
6 // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7 //
8 
9 #pragma once
10 
11 #include <immer/algorithm.hpp>
13 
14 namespace immer {
15 namespace detail {
16 namespace arrays {
17 
18 template <typename T, typename MemoryPolicy>
20 {
22  using edit_t = typename MemoryPolicy::transience_t::edit;
23  using size_t = std::size_t;
24 
26  size_t size;
27 
28  static const no_capacity& empty()
29  {
30  static const no_capacity empty_ {
31  node_t::make_n(0),
32  0,
33  };
34  return empty_;
35  }
36 
37  no_capacity(node_t* p, size_t s)
38  : ptr{p}, size{s}
39  {}
40 
41  no_capacity(const no_capacity& other)
42  : no_capacity{other.ptr, other.size}
43  {
44  inc();
45  }
46 
48  : no_capacity{empty()}
49  {
50  swap(*this, other);
51  }
52 
54  {
55  auto next = other;
56  swap(*this, next);
57  return *this;
58  }
59 
61  {
62  swap(*this, other);
63  return *this;
64  }
65 
66  friend void swap(no_capacity& x, no_capacity& y)
67  {
68  using std::swap;
69  swap(x.ptr, y.ptr);
70  swap(x.size, y.size);
71  }
72 
74  {
75  dec();
76  }
77 
78  void inc()
79  {
80  using immer::detail::get;
81  ptr->refs().inc();
82  }
83 
84  void dec()
85  {
86  using immer::detail::get;
87  if (ptr->refs().dec())
89  }
90 
91  T* data() { return ptr->data(); }
92  const T* data() const { return ptr->data(); }
93 
94  template <typename Iter, typename Sent,
95  std::enable_if_t
96  <is_forward_iterator_v<Iter>
97  && compatible_sentinel_v<Iter, Sent>, bool> = true>
98  static no_capacity from_range(Iter first, Sent last)
99  {
100  auto count = static_cast<size_t>(distance(first, last));
101  return {
102  node_t::copy_n(count, first, last),
103  count,
104  };
105  }
106 
107  static no_capacity from_fill(size_t n, T v)
108  {
109  return { node_t::fill_n(n, v), n };
110  }
111 
112  template <typename U>
113  static no_capacity from_initializer_list(std::initializer_list<U> values)
114  {
115  using namespace std;
116  return from_range(begin(values), end(values));
117  }
118 
119  template <typename Fn>
120  void for_each_chunk(Fn&& fn) const
121  {
122  std::forward<Fn>(fn)(data(), data() + size);
123  }
124 
125  template <typename Fn>
126  bool for_each_chunk_p(Fn&& fn) const
127  {
128  return std::forward<Fn>(fn)(data(), data() + size);
129  }
130 
131  const T& get(std::size_t index) const
132  {
133  return data()[index];
134  }
135 
136  const T& get_check(std::size_t index) const
137  {
138  if (index >= size)
139  throw std::out_of_range{"out of range"};
140  return data()[index];
141  }
142 
143  bool equals(const no_capacity& other) const
144  {
145  return ptr == other.ptr ||
146  (size == other.size &&
147  std::equal(data(), data() + size, other.data()));
148  }
149 
150  no_capacity push_back(T value) const
151  {
152  auto p = node_t::copy_n(size + 1, ptr, size);
153  try {
154  new (p->data() + size) T{std::move(value)};
155  return { p, size + 1 };
156  } catch (...) {
157  node_t::delete_n(p, size, size + 1);
158  throw;
159  }
160  }
161 
162  no_capacity assoc(std::size_t idx, T value) const
163  {
164  auto p = node_t::copy_n(size, ptr, size);
165  try {
166  p->data()[idx] = std::move(value);
167  return { p, size };
168  } catch (...) {
170  throw;
171  }
172  }
173 
174  template <typename Fn>
175  no_capacity update(std::size_t idx, Fn&& op) const
176  {
177  auto p = node_t::copy_n(size, ptr, size);
178  try {
179  auto& elem = p->data()[idx];
180  elem = std::forward<Fn>(op)(std::move(elem));
181  return { p, size };
182  } catch (...) {
184  throw;
185  }
186  }
187 
189  {
190  auto p = node_t::copy_n(sz, ptr, sz);
191  return { p, sz };
192  }
193 };
194 
195 } // namespace arrays
196 } // namespace detail
197 } // namespace immer
static no_capacity from_fill(size_t n, T v)
static node_t * copy_n(size_t n, Iter first, Sent last)
Definition: node.hpp:99
no_capacity update(std::size_t idx, Fn &&op) const
no_capacity push_back(T value) const
no_capacity assoc(std::size_t idx, T value) const
no_capacity(const no_capacity &other)
Definition: no_capacity.hpp:41
friend void swap(no_capacity &x, no_capacity &y)
Definition: no_capacity.hpp:66
void for_each_chunk(Fn &&fn) const
std::iterator_traits< Iterator >::difference_type distance(Iterator first, Sentinel last)
Definition: util.hpp:141
no_capacity & operator=(no_capacity &&other)
Definition: no_capacity.hpp:60
static node_t * fill_n(size_t n, T v)
Definition: node.hpp:84
bool for_each_chunk_p(Fn &&fn) const
Definition: box.hpp:161
static no_capacity from_initializer_list(std::initializer_list< U > values)
static node_t * make_n(size_t n)
Definition: node.hpp:72
no_capacity take(std::size_t sz) const
std::size_t size_t
Definition: bits.hpp:21
static void delete_n(node_t *p, size_t sz, size_t cap)
Definition: node.hpp:65
no_capacity(node_t *p, size_t s)
Definition: no_capacity.hpp:37
typename MemoryPolicy::transience_t::edit edit_t
Definition: no_capacity.hpp:22
static no_capacity from_range(Iter first, Sent last)
Definition: no_capacity.hpp:98
no_capacity & operator=(const no_capacity &other)
Definition: no_capacity.hpp:53
const T & get_check(std::size_t index) const
static const no_capacity & empty()
Definition: no_capacity.hpp:28
bool equals(const no_capacity &other) const
static int count
Definition: tests.c:45
const T * data() const
Definition: node.hpp:56
no_capacity(no_capacity &&other)
Definition: no_capacity.hpp:47
refs_t & refs() const
Definition: node.hpp:48
Released under the MIT license