20 #ifndef BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
21 #define BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
23 #include <ripple/beast/clock/abstract_clock.h>
24 #include <ripple/beast/container/aged_container.h>
25 #include <ripple/beast/container/detail/aged_associative_container.h>
26 #include <ripple/beast/container/detail/aged_container_iterator.h>
27 #include <ripple/beast/container/detail/empty_base_optimization.h>
28 #include <boost/intrusive/list.hpp>
29 #include <boost/intrusive/set.hpp>
30 #include <boost/version.hpp>
109 : boost::intrusive::set_base_hook<
110 boost::intrusive::link_mode<boost::intrusive::normal_link>>,
111 boost::intrusive::list_base_hook<
112 boost::intrusive::link_mode<boost::intrusive::normal_link>>
150 #ifdef _LIBCPP_VERSION
156 #ifndef _LIBCPP_VERSION
165 return this->member()(lhs.first, rhs.first);
190 #ifdef _LIBCPP_VERSION
196 #ifndef _LIBCPP_VERSION
213 bool operator() (K
const& k,
element const& e)
const
219 bool operator() (element
const& e, K
const& k)
const
221 return this->member() (
extract (e.value), k);
256 using list_type =
typename boost::intrusive::
257 make_list<element, boost::intrusive::constant_time_size<false>>::type;
261 typename boost::intrusive::make_multiset<
263 boost::intrusive::constant_time_size<true>,
264 boost::intrusive::compare<KeyValueCompare>>::type,
265 typename boost::intrusive::make_set<
267 boost::intrusive::constant_time_size<true>,
268 boost::intrusive::compare<KeyValueCompare>>::type>::type;
271 Allocator>::template rebind_alloc<element>;
298 Allocator
const& alloc_)
351 compare() = std::move(other.compare());
352 alloc() = std::move(other.alloc());
398 template <
class... Args>
410 operator()(element* p)
423 std::forward<Args>(args)...);
457 aged_container_iterator<!IsMap, typename cont_type::iterator>;
459 aged_container_iterator<true, typename cont_type::iterator>;
461 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
463 aged_container_iterator<true, typename cont_type::reverse_iterator>;
480 aged_container_iterator<!IsMap, typename list_type::iterator>;
482 aged_container_iterator<true, typename list_type::iterator>;
485 typename list_type::reverse_iterator>;
487 aged_container_iterator<true, typename list_type::reverse_iterator>;
566 "must be standard layout");
567 return list.iterator_to(*
reinterpret_cast<element*
>(
568 reinterpret_cast<uint8_t*
>(&value) -
577 "must be standard layout");
578 return list.iterator_to(*
reinterpret_cast<element const*
>(
579 reinterpret_cast<uint8_t const*
>(&value) -
612 Allocator
const& alloc);
614 template <
class InputIt>
617 template <
class InputIt>
622 Compare
const& comp);
624 template <
class InputIt>
629 Allocator
const& alloc);
631 template <
class InputIt>
637 Allocator
const& alloc);
643 Allocator
const& alloc);
649 Allocator
const& alloc);
658 Compare
const& comp);
663 Allocator
const& alloc);
669 Allocator
const& alloc);
708 bool maybe_multi = IsMulti,
709 bool maybe_map = IsMap,
716 bool maybe_multi = IsMulti,
717 bool maybe_map = IsMap,
720 at(K
const& k)
const;
723 bool maybe_multi = IsMulti,
724 bool maybe_map = IsMap,
730 bool maybe_multi = IsMulti,
731 bool maybe_map = IsMap,
819 return m_cont.iterator_to(*
reinterpret_cast<element*
>(
820 reinterpret_cast<uint8_t*
>(&value) -
829 return m_cont.iterator_to(*
reinterpret_cast<element const*
>(
830 reinterpret_cast<uint8_t const*
>(&value) -
868 template <
bool maybe_multi = IsMulti>
874 template <
bool maybe_multi = IsMulti>
880 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
883 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type;
886 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
894 template <
bool maybe_multi = IsMulti>
900 template <
bool maybe_multi = IsMulti>
909 template <
bool maybe_multi = IsMulti>
915 template <
bool maybe_multi = IsMulti>
920 return insert(std::move(value));
924 template <
class P,
bool maybe_map = IsMap>
928 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
932 return emplace(std::forward<P>(value));
936 template <
class P,
bool maybe_map = IsMap>
940 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
947 template <
class InputIt>
951 for (; first != last; ++first)
962 template <
bool maybe_multi = IsMulti,
class... Args>
968 template <
bool maybe_multi = IsMulti,
class... Args>
974 template <
bool maybe_multi = IsMulti,
class... Args>
980 template <
bool maybe_multi = IsMulti,
class... Args>
985 return emplace<maybe_multi>(std::forward<Args>(args)...);
1150 class OtherDuration,
1151 class OtherAllocator>
1160 OtherAllocator>
const& other)
const;
1166 class OtherDuration,
1167 class OtherAllocator>
1176 OtherAllocator>
const& other)
const
1185 class OtherDuration,
1186 class OtherAllocator>
1195 OtherAllocator>
const& other)
const
1199 cbegin(),
cend(), other.cbegin(), other.cend(), comp);
1206 class OtherDuration,
1207 class OtherAllocator>
1216 OtherAllocator>
const& other)
const
1218 return !(other < *
this);
1225 class OtherDuration,
1226 class OtherAllocator>
1235 OtherAllocator>
const& other)
const
1237 return other < *
this;
1244 class OtherDuration,
1245 class OtherAllocator>
1254 OtherAllocator>
const& other)
const
1256 return !(*
this < other);
1272 Allocator>::propagate_on_container_swap::value>
1278 Allocator>::propagate_on_container_swap::value>
1313 : m_config(clock, comp), m_cont(comp)
1327 : m_config(clock, alloc)
1342 Compare
const& comp,
1343 Allocator
const& alloc)
1344 : m_config(clock, comp, alloc), m_cont(comp)
1356 template <
class InputIt>
1361 insert(first, last);
1372 template <
class InputIt>
1378 Compare
const& comp)
1379 : m_config(clock, comp), m_cont(comp)
1381 insert(first, last);
1392 template <
class InputIt>
1398 Allocator
const& alloc)
1399 : m_config(clock, alloc)
1401 insert(first, last);
1412 template <
class InputIt>
1418 Compare
const& comp,
1419 Allocator
const& alloc)
1420 : m_config(clock, comp, alloc), m_cont(comp)
1422 insert(first, last);
1435 : m_config(other.m_config)
1436 #if BOOST_VERSION >= 108000
1437 , m_cont(other.m_cont.get_comp())
1439 , m_cont(other.m_cont.comp())
1456 Allocator
const& alloc)
1457 : m_config(other.m_config, alloc)
1458 #if BOOST_VERSION >= 108000
1459 , m_cont(other.m_cont.get_comp())
1461 , m_cont(other.m_cont.comp())
1477 : m_config(
std::move(other.m_config)), m_cont(
std::move(other.m_cont))
1479 chronological.list = std::move(other.chronological.list);
1493 Allocator
const& alloc)
1494 : m_config(
std::move(other.m_config), alloc)
1495 #if BOOST_VERSION >= 108000
1496 , m_cont(
std::move(other.m_cont.get_comp()))
1498 , m_cont(
std::move(other.m_cont.comp()))
1502 insert(other.cbegin(), other.cend());
1535 Compare
const& comp)
1536 : m_config(clock, comp), m_cont(comp)
1553 Allocator
const& alloc)
1554 : m_config(clock, alloc)
1571 Compare
const& comp,
1572 Allocator
const& alloc)
1573 : m_config(clock, comp, alloc), m_cont(comp)
1607 this->m_config = other.m_config;
1608 insert(other.begin(), other.end());
1626 this->m_config = std::move(other.m_config);
1627 insert(other.begin(), other.end());
1659 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1664 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1665 if (iter == m_cont.end())
1667 return iter->value.second;
1678 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1683 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1684 if (iter == m_cont.end())
1686 return iter->value.second;
1697 template <
bool maybe_multi,
bool maybe_map,
class>
1702 typename cont_type::insert_commit_data d;
1704 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1707 element*
const p(new_element(
1708 std::piecewise_construct,
1711 m_cont.insert_commit(*p, d);
1712 chronological.list.push_back(*p);
1713 return p->value.second;
1715 return result.first->value.second;
1726 template <
bool maybe_multi,
bool maybe_map,
class>
1731 typename cont_type::insert_commit_data d;
1733 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1736 element*
const p(new_element(
1737 std::piecewise_construct,
1740 m_cont.insert_commit(*p, d);
1741 chronological.list.push_back(*p);
1742 return p->value.second;
1744 return result.first->value.second;
1761 for (
auto iter(chronological.list.begin());
1762 iter != chronological.list.end();)
1763 delete_element(&*iter++);
1764 chronological.list.clear();
1777 template <
bool maybe_multi>
1783 typename cont_type::insert_commit_data d;
1784 auto const result(m_cont.insert_check(
1785 extract(value),
std::cref(m_config.key_compare()), d));
1788 element*
const p(new_element(value));
1789 auto const iter(m_cont.insert_commit(*p, d));
1790 chronological.list.push_back(*p);
1805 template <
bool maybe_multi>
1808 insert(value_type
const& value) ->
1812 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1813 element*
const p(new_element(value));
1814 chronological.list.push_back(*p);
1815 auto const iter(m_cont.insert_before(before, *p));
1816 return iterator(iter);
1828 template <
bool maybe_multi,
bool maybe_map>
1832 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1834 typename cont_type::insert_commit_data d;
1835 auto const result(m_cont.insert_check(
1836 extract(value),
std::cref(m_config.key_compare()), d));
1839 element*
const p(new_element(std::move(value)));
1840 auto const iter(m_cont.insert_commit(*p, d));
1841 chronological.list.push_back(*p);
1856 template <
bool maybe_multi,
bool maybe_map>
1859 insert(value_type&& value) ->
1863 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1864 element*
const p(new_element(std::move(value)));
1865 chronological.list.push_back(*p);
1866 auto const iter(m_cont.insert_before(before, *p));
1867 return iterator(iter);
1881 template <
bool maybe_multi>
1887 typename cont_type::insert_commit_data d;
1888 auto const result(m_cont.insert_check(
1889 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1892 element*
const p(new_element(value));
1893 auto const iter(m_cont.insert_commit(*p, d));
1894 chronological.list.push_back(*p);
1909 template <
bool maybe_multi>
1915 typename cont_type::insert_commit_data d;
1916 auto const result(m_cont.insert_check(
1917 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1920 element*
const p(new_element(std::move(value)));
1921 auto const iter(m_cont.insert_commit(*p, d));
1922 chronological.list.push_back(*p);
1937 template <
bool maybe_multi,
class... Args>
1945 element*
const p(new_element(std::forward<Args>(args)...));
1946 typename cont_type::insert_commit_data d;
1947 auto const result(m_cont.insert_check(
1948 extract(p->value),
std::cref(m_config.key_compare()), d));
1951 auto const iter(m_cont.insert_commit(*p, d));
1952 chronological.list.push_back(*p);
1968 template <
bool maybe_multi,
class... Args>
1974 element*
const p(new_element(std::forward<Args>(args)...));
1975 auto const before(m_cont.upper_bound(
1976 extract(p->value),
std::cref(m_config.key_compare())));
1977 chronological.list.push_back(*p);
1978 auto const iter(m_cont.insert_before(before, *p));
1979 return iterator(iter);
1991 template <
bool maybe_multi,
class... Args>
1999 element*
const p(new_element(std::forward<Args>(args)...));
2000 typename cont_type::insert_commit_data d;
2001 auto const result(m_cont.insert_check(
2008 auto const iter(m_cont.insert_commit(*p, d));
2009 chronological.list.push_back(*p);
2024 template <
bool is_const,
class Iterator,
class>
2029 unlink_and_delete_element(&*((pos++).
iterator()));
2042 template <
bool is_const,
class Iterator,
class>
2049 for (; first != last;)
2050 unlink_and_delete_element(&*((first++).
iterator()));
2069 auto iter(m_cont.find(k,
std::cref(m_config.key_compare())));
2070 if (iter == m_cont.end())
2076 bool const done(m_config(*p, extract(iter->value)));
2077 unlink_and_delete_element(p);
2098 std::swap(chronological, other.chronological);
2117 auto const now(clock().now());
2119 auto const range(equal_range(k));
2120 for (
auto iter : range)
2142 class OtherDuration,
2143 class OtherAllocator>
2153 OtherAllocator>
const& other)
const
2163 if (size() != other.size())
2172 value_type const& lhs,
typename Other::value_type
const& rhs) {
2173 return eq(extract(lhs), other.extract(rhs));
2187 template <
bool is_const,
class Iterator,
class>
2196 chronological.list.erase(chronological.list.iterator_to(e));
2197 chronological.list.push_back(e);
2208 template <
bool maybe_propagate>
2213 std::swap(m_config.key_compare(), other.m_config.key_compare());
2214 std::swap(m_config.alloc(), other.m_config.alloc());
2215 std::swap(m_config.clock, other.m_config.clock);
2226 template <
bool maybe_propagate>
2231 std::swap(m_config.key_compare(), other.m_config.key_compare());
2232 std::swap(m_config.clock, other.m_config.clock);
2286 Allocator>& rhs) noexcept
2315 auto const expired(c.clock().now() - age);
2316 for (
auto iter(c.chronological.cbegin());
2317 iter != c.chronological.cend() && iter.when() <= expired;)
2319 iter = c.erase(iter);