23 explicit Container(size_t max_size)
29 template <
typename... Args>
31 auto& seq_index = get_sequenced();
33 std::pair<
decltype(seq_index.begin()),
bool> result;
35 if (free_nodes_.size() > 0) {
36 auto node = std::move(free_nodes_.back());
37 free_nodes_.pop_back();
39 node.value() = Value(std::forward<Args>(args)...);
40 auto ret = seq_index.insert(seq_index.begin(), std::move(node));
41 result = {ret.position, ret.inserted};
43 result = seq_index.emplace_front(std::forward<Args>(args)...);
46 seq_index.relocate(seq_index.begin(), result.first);
47 }
else if (seq_index.size() > max_size_) {
48 free_nodes_.emplace_back(seq_index.extract(std::prev(seq_index.end())));
53 bool insert(
const Value& value) {
return emplace(value).second; }
55 bool insert(Value&& value) {
return emplace(std::move(value)).second; }
57 template <
typename Tag,
typename Key>
58 auto find(
const Key& key) {
59 auto& primary_index = get_index<Tag>();
60 auto it = primary_index.find(key);
62 if (it != primary_index.end()) {
63 auto& seq_index = get_sequenced();
64 auto seq_it = container_.
template project<0>(it);
65 seq_index.relocate(seq_index.begin(), seq_it);
71 template <
typename Tag,
typename Key>
72 auto find_no_update(
const Key& key)
const {
73 return get_index<Tag>().find(key);
77 template <
typename Tag,
typename Key>
79 auto& primary_index = get_index<Tag>();
81 auto [begin, end] = primary_index.equal_range(key);
84 auto& seq_index = get_sequenced();
86 seq_index.relocate(seq_index.begin(), project_to_sequenced(it));
90 return std::pair{begin, end};
94 template <
typename Tag,
typename Key>
96 return get_index<Tag>().equal_range(key);
99 template <
typename Tag,
typename Key>
100 bool contains(
const Key& key) {
101 return this->
template find<Tag, Key>(key) != end<Tag>();
104 template <
typename Tag,
typename Key>
105 bool contains_no_update(
const Key& key)
const {
106 return this->
template find_no_update<Tag, Key>(key) != end<Tag>();
111 template <
typename IteratorType>
113 auto it_0 = project_to_sequenced(it);
114 auto& seq_index = get_sequenced();
115 if (it_0 == seq_index.end()) {
120 free_nodes_.emplace_back(seq_index.extract(it_0));
126 template <
typename Tag,
typename Key>
128 auto it = find_no_update<Tag, Key>(key);
129 return erase(it) != end<Tag>();
132 std::size_t size()
const noexcept {
return container_.size(); }
134 bool empty()
const noexcept {
return container_.empty(); }
136 std::size_t capacity()
const noexcept {
return max_size_; }
138 void set_capacity(std::size_t new_capacity) {
139 max_size_ = new_capacity;
140 if (container_.size() <= max_size_) {
145 auto& seq_index = get_sequenced();
146 while (container_.size() > max_size_) {
148 seq_index.extract(std::prev(seq_index.end()));
158 auto& seq_index = get_sequenced();
159 free_nodes_.reserve(free_nodes_.size() + container_.size());
160 while (!container_.empty()) {
161 free_nodes_.emplace_back(seq_index.extract(std::prev(seq_index.end())));
166 template <
typename Tag>
168 return get_index<Tag>().end();
171 auto find_last_accessed_no_update()
const {
return std::prev(get_sequenced().end()); }
174 using ExtendedIndexSpecifierList = impl::add_index_t<boost::multi_index::sequenced<>, IndexSpecifierList>;
175 using BoostContainer = boost::multi_index::multi_index_container<Value, ExtendedIndexSpecifierList, Allocator>;
177 BoostContainer container_;
178 std::size_t max_size_;
179 std::vector<
typename BoostContainer::node_type> free_nodes_;
181 auto& get_sequenced()
noexcept {
return container_.
template get<0>(); }
183 const auto& get_sequenced()
const noexcept {
return container_.
template get<0>(); }
185 template <
typename Tag>
187 return container_.
template get<Tag>();
190 template <
typename Tag>
191 const auto& get_index()
const noexcept {
192 return container_.
template get<Tag>();
195 template <
typename IterT>
196 auto project_to_sequenced(IterT it) {
197 return container_.
template project<0>(it);