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), m_cont(other.m_cont.comp())
1451 Allocator
const& alloc)
1452 : m_config(other.m_config, alloc), m_cont(other.m_cont.comp())
1467 : m_config(
std::move(other.m_config)), m_cont(
std::move(other.m_cont))
1469 chronological.list = std::move(other.chronological.list);
1483 Allocator
const& alloc)
1484 : m_config(
std::move(other.m_config), alloc)
1485 , m_cont(
std::move(other.m_cont.comp()))
1487 insert(other.cbegin(), other.cend());
1520 Compare
const& comp)
1521 : m_config(clock, comp), m_cont(comp)
1538 Allocator
const& alloc)
1539 : m_config(clock, alloc)
1556 Compare
const& comp,
1557 Allocator
const& alloc)
1558 : m_config(clock, comp, alloc), m_cont(comp)
1592 this->m_config = other.m_config;
1593 insert(other.begin(), other.end());
1611 this->m_config = std::move(other.m_config);
1612 insert(other.begin(), other.end());
1644 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1649 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1650 if (iter == m_cont.end())
1652 return iter->value.second;
1663 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1668 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1669 if (iter == m_cont.end())
1671 return iter->value.second;
1682 template <
bool maybe_multi,
bool maybe_map,
class>
1687 typename cont_type::insert_commit_data d;
1689 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1692 element*
const p(new_element(
1693 std::piecewise_construct,
1696 m_cont.insert_commit(*p, d);
1697 chronological.list.push_back(*p);
1698 return p->value.second;
1700 return result.first->value.second;
1711 template <
bool maybe_multi,
bool maybe_map,
class>
1716 typename cont_type::insert_commit_data d;
1718 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1721 element*
const p(new_element(
1722 std::piecewise_construct,
1725 m_cont.insert_commit(*p, d);
1726 chronological.list.push_back(*p);
1727 return p->value.second;
1729 return result.first->value.second;
1746 for (
auto iter(chronological.list.begin());
1747 iter != chronological.list.end();)
1748 delete_element(&*iter++);
1749 chronological.list.clear();
1762 template <
bool maybe_multi>
1768 typename cont_type::insert_commit_data d;
1769 auto const result(m_cont.insert_check(
1770 extract(value),
std::cref(m_config.key_compare()), d));
1773 element*
const p(new_element(value));
1774 auto const iter(m_cont.insert_commit(*p, d));
1775 chronological.list.push_back(*p);
1790 template <
bool maybe_multi>
1793 insert(value_type
const& value) ->
1797 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1798 element*
const p(new_element(value));
1799 chronological.list.push_back(*p);
1800 auto const iter(m_cont.insert_before(before, *p));
1801 return iterator(iter);
1813 template <
bool maybe_multi,
bool maybe_map>
1817 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1819 typename cont_type::insert_commit_data d;
1820 auto const result(m_cont.insert_check(
1821 extract(value),
std::cref(m_config.key_compare()), d));
1824 element*
const p(new_element(std::move(value)));
1825 auto const iter(m_cont.insert_commit(*p, d));
1826 chronological.list.push_back(*p);
1841 template <
bool maybe_multi,
bool maybe_map>
1844 insert(value_type&& value) ->
1848 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1849 element*
const p(new_element(std::move(value)));
1850 chronological.list.push_back(*p);
1851 auto const iter(m_cont.insert_before(before, *p));
1852 return iterator(iter);
1866 template <
bool maybe_multi>
1872 typename cont_type::insert_commit_data d;
1873 auto const result(m_cont.insert_check(
1874 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1877 element*
const p(new_element(value));
1878 auto const iter(m_cont.insert_commit(*p, d));
1879 chronological.list.push_back(*p);
1894 template <
bool maybe_multi>
1900 typename cont_type::insert_commit_data d;
1901 auto const result(m_cont.insert_check(
1902 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1905 element*
const p(new_element(std::move(value)));
1906 auto const iter(m_cont.insert_commit(*p, d));
1907 chronological.list.push_back(*p);
1922 template <
bool maybe_multi,
class... Args>
1930 element*
const p(new_element(std::forward<Args>(args)...));
1931 typename cont_type::insert_commit_data d;
1932 auto const result(m_cont.insert_check(
1933 extract(p->value),
std::cref(m_config.key_compare()), d));
1936 auto const iter(m_cont.insert_commit(*p, d));
1937 chronological.list.push_back(*p);
1953 template <
bool maybe_multi,
class... Args>
1959 element*
const p(new_element(std::forward<Args>(args)...));
1960 auto const before(m_cont.upper_bound(
1961 extract(p->value),
std::cref(m_config.key_compare())));
1962 chronological.list.push_back(*p);
1963 auto const iter(m_cont.insert_before(before, *p));
1964 return iterator(iter);
1976 template <
bool maybe_multi,
class... Args>
1984 element*
const p(new_element(std::forward<Args>(args)...));
1985 typename cont_type::insert_commit_data d;
1986 auto const result(m_cont.insert_check(
1993 auto const iter(m_cont.insert_commit(*p, d));
1994 chronological.list.push_back(*p);
2009 template <
bool is_const,
class Iterator,
class>
2014 unlink_and_delete_element(&*((pos++).
iterator()));
2027 template <
bool is_const,
class Iterator,
class>
2034 for (; first != last;)
2035 unlink_and_delete_element(&*((first++).
iterator()));
2054 auto iter(m_cont.find(k,
std::cref(m_config.key_compare())));
2055 if (iter == m_cont.end())
2061 bool const done(m_config(*p, extract(iter->value)));
2062 unlink_and_delete_element(p);
2083 std::swap(chronological, other.chronological);
2102 auto const now(clock().now());
2104 auto const range(equal_range(k));
2105 for (
auto iter : range)
2127 class OtherDuration,
2128 class OtherAllocator>
2138 OtherAllocator>
const& other)
const
2148 if (size() != other.size())
2157 value_type const& lhs,
typename Other::value_type
const& rhs) {
2158 return eq(extract(lhs), other.extract(rhs));
2172 template <
bool is_const,
class Iterator,
class>
2181 chronological.list.erase(chronological.list.iterator_to(e));
2182 chronological.list.push_back(e);
2193 template <
bool maybe_propagate>
2198 std::swap(m_config.key_compare(), other.m_config.key_compare());
2199 std::swap(m_config.alloc(), other.m_config.alloc());
2200 std::swap(m_config.clock, other.m_config.clock);
2211 template <
bool maybe_propagate>
2216 std::swap(m_config.key_compare(), other.m_config.key_compare());
2217 std::swap(m_config.clock, other.m_config.clock);
2271 Allocator>& rhs) noexcept
2300 auto const expired(c.clock().now() - age);
2301 for (
auto iter(c.chronological.cbegin());
2302 iter != c.chronological.cend() && iter.when() <= expired;)
2304 iter = c.erase(iter);