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/experimental/detail/dvektor_impl.hpp> |
12 | #include <immer/memory_policy.hpp> |
13 | |
14 | namespace immer { |
15 | |
16 | template <typename T, |
17 | int B = 5, |
18 | typename MemoryPolicy = default_memory_policy> |
19 | class dvektor |
20 | { |
21 | using impl_t = detail::dvektor::impl<T, B, MemoryPolicy>; |
22 | |
23 | public: |
24 | using value_type = T; |
25 | using reference = const T&; |
26 | using size_type = std::size_t; |
27 | using difference_type = std::ptrdiff_t; |
28 | using const_reference = const T&; |
29 | |
30 | using iterator = detail::dvektor::iterator<T, B, MemoryPolicy>; |
31 | using const_iterator = iterator; |
32 | using reverse_iterator = std::reverse_iterator<iterator>; |
33 | |
34 | dvektor() = default; |
35 | |
36 | iterator begin() const { return {impl_}; } |
37 | iterator end() const { return {impl_, typename iterator::end_t{}}; } |
38 | |
39 | reverse_iterator rbegin() const { return reverse_iterator{end()}; } |
40 | reverse_iterator rend() const { return reverse_iterator{begin()}; } |
41 | |
42 | std::size_t size() const { return impl_.size; } |
43 | bool empty() const { return impl_.size == 0; } |
44 | |
45 | reference operator[] (size_type index) const |
46 | { return impl_.get(index); } |
47 | |
48 | dvektor push_back(value_type value) const |
49 | { return { impl_.push_back(std::move(value)) }; } |
50 | |
51 | dvektor assoc(std::size_t idx, value_type value) const |
52 | { return { impl_.assoc(idx, std::move(value)) }; } |
53 | |
54 | template <typename FnT> |
55 | dvektor update(std::size_t idx, FnT&& fn) const |
56 | { return { impl_.update(idx, std::forward<FnT>(fn)) }; } |
57 | |
58 | private: |
59 | dvektor(impl_t impl) : impl_(std::move(impl)) {} |
60 | impl_t impl_ = detail::dvektor::empty<T, B, MemoryPolicy>; |
61 | }; |
62 | |
63 | } // namespace immer |
64 | |