Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/capy
8 : //
9 :
10 : #include <boost/capy/polystore.hpp>
11 : #include <utility>
12 :
13 : namespace boost {
14 : namespace capy {
15 :
16 12 : polystore::
17 : ~polystore()
18 : {
19 12 : destroy();
20 12 : }
21 :
22 0 : polystore::
23 : polystore(
24 0 : polystore&& other) noexcept
25 : {
26 : using std::swap;
27 0 : swap(v_, other.v_);
28 0 : swap(m_, other.m_);
29 0 : }
30 :
31 : polystore&
32 0 : polystore::
33 : operator=(
34 : polystore&& other) noexcept
35 : {
36 0 : if(this != &other)
37 : {
38 : using std::swap;
39 0 : polystore tmp(std::move(*this));
40 0 : swap(v_, tmp.v_);
41 0 : swap(m_, tmp.m_);
42 0 : swap(v_, other.v_);
43 0 : swap(m_, other.m_);
44 0 : }
45 0 : return *this;
46 : }
47 :
48 : void
49 1 : polystore::
50 : clear() noexcept
51 : {
52 1 : destroy();
53 1 : m_.clear();
54 1 : }
55 :
56 : auto
57 0 : polystore::
58 : get_elements() noexcept ->
59 : elements
60 : {
61 0 : return elements(v_.size(), *this);
62 : }
63 :
64 : void
65 13 : polystore::
66 : destroy() noexcept
67 : {
68 : // destroy in reverse order
69 27 : for(auto n = v_.size(); n--;)
70 14 : v_.resize(n);
71 13 : }
72 :
73 : auto
74 0 : polystore::
75 : get(std::size_t i) -> any&
76 : {
77 0 : return *v_[i];
78 : }
79 :
80 : void*
81 66 : polystore::
82 : find(
83 : core::typeinfo const& ti) const noexcept
84 : {
85 66 : auto const it = m_.find(ti);
86 66 : if(it == m_.end())
87 10 : return nullptr;
88 56 : return it->second;
89 : }
90 :
91 : void*
92 18 : polystore::
93 : insert_impl(
94 : any_ptr p, key const* k, std::size_t n)
95 : {
96 : struct do_insert
97 : {
98 : any_ptr p;
99 : key const* k;
100 : std::size_t n;
101 : polystore& ps;
102 : std::size_t i = 0;
103 :
104 18 : do_insert(
105 : any_ptr p_,
106 : key const* k_,
107 : std::size_t n_,
108 : polystore& ps_)
109 18 : : p(std::move(p_)), k(k_), n(n_), ps(ps_)
110 : {
111 : // ensure emplace_back can't fail
112 18 : ps.v_.reserve(ps.v_.size() + 1);
113 :
114 39 : for(;i < n;++i)
115 25 : if(! ps.m_.emplace(k[i].ti, k[i].p).second)
116 4 : detail::throw_invalid_argument(
117 : "polystore: duplicate key");
118 :
119 14 : ps.v_.emplace_back(std::move(p));
120 18 : }
121 :
122 14 : ~do_insert()
123 0 : {
124 14 : if(i == n)
125 14 : return;
126 0 : while(i--)
127 0 : ps.m_.erase(k[i].ti);
128 14 : }
129 : };
130 :
131 18 : auto const pt = p->get();
132 22 : do_insert(std::move(p), k, n, *this);
133 14 : return pt;
134 : }
135 :
136 : } // capy
137 : } // boost
|