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>>
158 return Compare::operator()(lhs.first, rhs.first);
223 using list_type =
typename boost::intrusive::
224 make_list<element, boost::intrusive::constant_time_size<false>>::type;
228 typename boost::intrusive::make_multiset<
230 boost::intrusive::constant_time_size<true>,
231 boost::intrusive::compare<KeyValueCompare>>::type,
232 typename boost::intrusive::make_set<
234 boost::intrusive::constant_time_size<true>,
235 boost::intrusive::compare<KeyValueCompare>>::type>::type;
238 Allocator>::template rebind_alloc<element>;
265 Allocator
const& alloc_)
318 compare() = std::move(other.compare());
319 alloc() = std::move(other.alloc());
365 template <
class... Args>
377 operator()(element* p)
390 std::forward<Args>(args)...);
424 aged_container_iterator<!IsMap, typename cont_type::iterator>;
426 aged_container_iterator<true, typename cont_type::iterator>;
428 aged_container_iterator<!IsMap, typename cont_type::reverse_iterator>;
430 aged_container_iterator<true, typename cont_type::reverse_iterator>;
447 aged_container_iterator<!IsMap, typename list_type::iterator>;
449 aged_container_iterator<true, typename list_type::iterator>;
452 typename list_type::reverse_iterator>;
454 aged_container_iterator<true, typename list_type::reverse_iterator>;
533 "must be standard layout");
534 return list.iterator_to(*
reinterpret_cast<element*
>(
535 reinterpret_cast<uint8_t*
>(&value) -
544 "must be standard layout");
545 return list.iterator_to(*
reinterpret_cast<element const*
>(
546 reinterpret_cast<uint8_t const*
>(&value) -
579 Allocator
const& alloc);
581 template <
class InputIt>
584 template <
class InputIt>
589 Compare
const& comp);
591 template <
class InputIt>
596 Allocator
const& alloc);
598 template <
class InputIt>
604 Allocator
const& alloc);
610 Allocator
const& alloc);
616 Allocator
const& alloc);
625 Compare
const& comp);
630 Allocator
const& alloc);
636 Allocator
const& alloc);
675 bool maybe_multi = IsMulti,
676 bool maybe_map = IsMap,
683 bool maybe_multi = IsMulti,
684 bool maybe_map = IsMap,
687 at(K
const& k)
const;
690 bool maybe_multi = IsMulti,
691 bool maybe_map = IsMap,
697 bool maybe_multi = IsMulti,
698 bool maybe_map = IsMap,
786 return m_cont.iterator_to(*
reinterpret_cast<element*
>(
787 reinterpret_cast<uint8_t*
>(&value) -
796 return m_cont.iterator_to(*
reinterpret_cast<element const*
>(
797 reinterpret_cast<uint8_t const*
>(&value) -
835 template <
bool maybe_multi = IsMulti>
841 template <
bool maybe_multi = IsMulti>
847 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
850 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type;
853 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
861 template <
bool maybe_multi = IsMulti>
867 template <
bool maybe_multi = IsMulti>
876 template <
bool maybe_multi = IsMulti>
882 template <
bool maybe_multi = IsMulti>
887 return insert(std::move(value));
891 template <
class P,
bool maybe_map = IsMap>
895 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
899 return emplace(std::forward<P>(value));
903 template <
class P,
bool maybe_map = IsMap>
907 conditional<IsMulti, iterator, std::pair<iterator, bool>>::type>::
914 template <
class InputIt>
918 for (; first != last; ++first)
929 template <
bool maybe_multi = IsMulti,
class... Args>
935 template <
bool maybe_multi = IsMulti,
class... Args>
941 template <
bool maybe_multi = IsMulti,
class... Args>
947 template <
bool maybe_multi = IsMulti,
class... Args>
952 return emplace<maybe_multi>(std::forward<Args>(args)...);
1117 class OtherDuration,
1118 class OtherAllocator>
1127 OtherAllocator>
const& other)
const;
1133 class OtherDuration,
1134 class OtherAllocator>
1143 OtherAllocator>
const& other)
const
1152 class OtherDuration,
1153 class OtherAllocator>
1162 OtherAllocator>
const& other)
const
1166 cbegin(),
cend(), other.cbegin(), other.cend(), comp);
1173 class OtherDuration,
1174 class OtherAllocator>
1183 OtherAllocator>
const& other)
const
1185 return !(other < *
this);
1192 class OtherDuration,
1193 class OtherAllocator>
1202 OtherAllocator>
const& other)
const
1204 return other < *
this;
1211 class OtherDuration,
1212 class OtherAllocator>
1221 OtherAllocator>
const& other)
const
1223 return !(*
this < other);
1239 Allocator>::propagate_on_container_swap::value>
1245 Allocator>::propagate_on_container_swap::value>
1280 : m_config(clock, comp), m_cont(comp)
1294 : m_config(clock, alloc)
1309 Compare
const& comp,
1310 Allocator
const& alloc)
1311 : m_config(clock, comp, alloc), m_cont(comp)
1323 template <
class InputIt>
1328 insert(first, last);
1339 template <
class InputIt>
1345 Compare
const& comp)
1346 : m_config(clock, comp), m_cont(comp)
1348 insert(first, last);
1359 template <
class InputIt>
1365 Allocator
const& alloc)
1366 : m_config(clock, alloc)
1368 insert(first, last);
1379 template <
class InputIt>
1385 Compare
const& comp,
1386 Allocator
const& alloc)
1387 : m_config(clock, comp, alloc), m_cont(comp)
1389 insert(first, last);
1402 : m_config(other.m_config)
1403 #if BOOST_VERSION >= 108000
1404 , m_cont(other.m_cont.get_comp())
1406 , m_cont(other.m_cont.comp())
1423 Allocator
const& alloc)
1424 : m_config(other.m_config, alloc)
1425 #if BOOST_VERSION >= 108000
1426 , m_cont(other.m_cont.get_comp())
1428 , m_cont(other.m_cont.comp())
1444 : m_config(
std::move(other.m_config)), m_cont(
std::move(other.m_cont))
1446 chronological.list = std::move(other.chronological.list);
1460 Allocator
const& alloc)
1461 : m_config(
std::move(other.m_config), alloc)
1462 #if BOOST_VERSION >= 108000
1463 , m_cont(
std::move(other.m_cont.get_comp()))
1465 , m_cont(
std::move(other.m_cont.comp()))
1469 insert(other.cbegin(), other.cend());
1502 Compare
const& comp)
1503 : m_config(clock, comp), m_cont(comp)
1520 Allocator
const& alloc)
1521 : m_config(clock, alloc)
1538 Compare
const& comp,
1539 Allocator
const& alloc)
1540 : m_config(clock, comp, alloc), m_cont(comp)
1574 this->m_config = other.m_config;
1575 insert(other.begin(), other.end());
1593 this->m_config = std::move(other.m_config);
1594 insert(other.begin(), other.end());
1626 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1631 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1632 if (iter == m_cont.end())
1634 return iter->value.second;
1645 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1650 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1651 if (iter == m_cont.end())
1653 return iter->value.second;
1664 template <
bool maybe_multi,
bool maybe_map,
class>
1669 typename cont_type::insert_commit_data d;
1671 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1674 element*
const p(new_element(
1675 std::piecewise_construct,
1678 m_cont.insert_commit(*p, d);
1679 chronological.list.push_back(*p);
1680 return p->value.second;
1682 return result.first->value.second;
1693 template <
bool maybe_multi,
bool maybe_map,
class>
1698 typename cont_type::insert_commit_data d;
1700 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1703 element*
const p(new_element(
1704 std::piecewise_construct,
1707 m_cont.insert_commit(*p, d);
1708 chronological.list.push_back(*p);
1709 return p->value.second;
1711 return result.first->value.second;
1728 for (
auto iter(chronological.list.begin());
1729 iter != chronological.list.end();)
1730 delete_element(&*iter++);
1731 chronological.list.clear();
1744 template <
bool maybe_multi>
1750 typename cont_type::insert_commit_data d;
1751 auto const result(m_cont.insert_check(
1752 extract(value),
std::cref(m_config.key_compare()), d));
1755 element*
const p(new_element(value));
1756 auto const iter(m_cont.insert_commit(*p, d));
1757 chronological.list.push_back(*p);
1772 template <
bool maybe_multi>
1775 insert(value_type
const& value) ->
1779 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1780 element*
const p(new_element(value));
1781 chronological.list.push_back(*p);
1782 auto const iter(m_cont.insert_before(before, *p));
1783 return iterator(iter);
1795 template <
bool maybe_multi,
bool maybe_map>
1799 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1801 typename cont_type::insert_commit_data d;
1802 auto const result(m_cont.insert_check(
1803 extract(value),
std::cref(m_config.key_compare()), d));
1806 element*
const p(new_element(std::move(value)));
1807 auto const iter(m_cont.insert_commit(*p, d));
1808 chronological.list.push_back(*p);
1823 template <
bool maybe_multi,
bool maybe_map>
1826 insert(value_type&& value) ->
1830 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1831 element*
const p(new_element(std::move(value)));
1832 chronological.list.push_back(*p);
1833 auto const iter(m_cont.insert_before(before, *p));
1834 return iterator(iter);
1848 template <
bool maybe_multi>
1854 typename cont_type::insert_commit_data d;
1855 auto const result(m_cont.insert_check(
1856 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1859 element*
const p(new_element(value));
1860 auto const iter(m_cont.insert_commit(*p, d));
1861 chronological.list.push_back(*p);
1876 template <
bool maybe_multi>
1882 typename cont_type::insert_commit_data d;
1883 auto const result(m_cont.insert_check(
1884 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1887 element*
const p(new_element(std::move(value)));
1888 auto const iter(m_cont.insert_commit(*p, d));
1889 chronological.list.push_back(*p);
1904 template <
bool maybe_multi,
class... Args>
1912 element*
const p(new_element(std::forward<Args>(args)...));
1913 typename cont_type::insert_commit_data d;
1914 auto const result(m_cont.insert_check(
1915 extract(p->value),
std::cref(m_config.key_compare()), d));
1918 auto const iter(m_cont.insert_commit(*p, d));
1919 chronological.list.push_back(*p);
1935 template <
bool maybe_multi,
class... Args>
1941 element*
const p(new_element(std::forward<Args>(args)...));
1942 auto const before(m_cont.upper_bound(
1943 extract(p->value),
std::cref(m_config.key_compare())));
1944 chronological.list.push_back(*p);
1945 auto const iter(m_cont.insert_before(before, *p));
1946 return iterator(iter);
1958 template <
bool maybe_multi,
class... Args>
1966 element*
const p(new_element(std::forward<Args>(args)...));
1967 typename cont_type::insert_commit_data d;
1968 auto const result(m_cont.insert_check(
1975 auto const iter(m_cont.insert_commit(*p, d));
1976 chronological.list.push_back(*p);
1991 template <
bool is_const,
class Iterator,
class>
1996 unlink_and_delete_element(&*((pos++).
iterator()));
2009 template <
bool is_const,
class Iterator,
class>
2016 for (; first != last;)
2017 unlink_and_delete_element(&*((first++).
iterator()));
2036 auto iter(m_cont.find(k,
std::cref(m_config.key_compare())));
2037 if (iter == m_cont.end())
2043 bool const done(m_config(*p, extract(iter->value)));
2044 unlink_and_delete_element(p);
2065 std::swap(chronological, other.chronological);
2084 auto const now(clock().now());
2086 auto const range(equal_range(k));
2087 for (
auto iter : range)
2109 class OtherDuration,
2110 class OtherAllocator>
2120 OtherAllocator>
const& other)
const
2130 if (size() != other.size())
2139 value_type const& lhs,
typename Other::value_type
const& rhs) {
2140 return eq(extract(lhs), other.extract(rhs));
2154 template <
bool is_const,
class Iterator,
class>
2163 chronological.list.erase(chronological.list.iterator_to(e));
2164 chronological.list.push_back(e);
2175 template <
bool maybe_propagate>
2180 std::swap(m_config.key_compare(), other.m_config.key_compare());
2181 std::swap(m_config.alloc(), other.m_config.alloc());
2182 std::swap(m_config.clock, other.m_config.clock);
2193 template <
bool maybe_propagate>
2198 std::swap(m_config.key_compare(), other.m_config.key_compare());
2199 std::swap(m_config.clock, other.m_config.clock);
2253 Allocator>& rhs) noexcept
2282 auto const expired(c.clock().now() - age);
2283 for (
auto iter(c.chronological.cbegin());
2284 iter != c.chronological.cend() && iter.when() <= expired;)
2286 iter = c.erase(iter);