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)...);
1153 class OtherDuration,
1154 class OtherAllocator>
1163 OtherAllocator>
const& other)
const;
1169 class OtherDuration,
1170 class OtherAllocator>
1179 OtherAllocator>
const& other)
const
1188 class OtherDuration,
1189 class OtherAllocator>
1198 OtherAllocator>
const& other)
const
1202 cbegin(),
cend(), other.cbegin(), other.cend(), comp);
1209 class OtherDuration,
1210 class OtherAllocator>
1219 OtherAllocator>
const& other)
const
1221 return !(other < *
this);
1228 class OtherDuration,
1229 class OtherAllocator>
1238 OtherAllocator>
const& other)
const
1240 return other < *
this;
1247 class OtherDuration,
1248 class OtherAllocator>
1257 OtherAllocator>
const& other)
const
1259 return !(*
this < other);
1276 Allocator>::propagate_on_container_swap::value>
1282 Allocator>::propagate_on_container_swap::value>
1317 : m_config(clock, comp), m_cont(comp)
1331 : m_config(clock, alloc)
1346 Compare
const& comp,
1347 Allocator
const& alloc)
1348 : m_config(clock, comp, alloc), m_cont(comp)
1360 template <
class InputIt>
1365 insert(first, last);
1376 template <
class InputIt>
1382 Compare
const& comp)
1383 : m_config(clock, comp), m_cont(comp)
1385 insert(first, last);
1396 template <
class InputIt>
1402 Allocator
const& alloc)
1403 : m_config(clock, alloc)
1405 insert(first, last);
1416 template <
class InputIt>
1422 Compare
const& comp,
1423 Allocator
const& alloc)
1424 : m_config(clock, comp, alloc), m_cont(comp)
1426 insert(first, last);
1439 : m_config(other.m_config), m_cont(other.m_cont.comp())
1455 Allocator
const& alloc)
1456 : m_config(other.m_config, alloc), m_cont(other.m_cont.comp())
1471 : m_config(
std::move(other.m_config)), m_cont(
std::move(other.m_cont))
1473 chronological.list = std::move(other.chronological.list);
1487 Allocator
const& alloc)
1488 : m_config(
std::move(other.m_config), alloc)
1489 , m_cont(
std::move(other.m_cont.comp()))
1491 insert(other.cbegin(), other.cend());
1524 Compare
const& comp)
1525 : m_config(clock, comp), m_cont(comp)
1542 Allocator
const& alloc)
1543 : m_config(clock, alloc)
1560 Compare
const& comp,
1561 Allocator
const& alloc)
1562 : m_config(clock, comp, alloc), m_cont(comp)
1596 this->m_config = other.m_config;
1597 insert(other.begin(), other.end());
1615 this->m_config = std::move(other.m_config);
1616 insert(other.begin(), other.end());
1648 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1653 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1654 if (iter == m_cont.end())
1656 return iter->value.second;
1667 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1672 auto const iter(m_cont.find(k,
std::cref(m_config.key_compare())));
1673 if (iter == m_cont.end())
1675 return iter->value.second;
1686 template <
bool maybe_multi,
bool maybe_map,
class>
1691 typename cont_type::insert_commit_data d;
1693 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1696 element*
const p(new_element(
1697 std::piecewise_construct,
1700 m_cont.insert_commit(*p, d);
1701 chronological.list.push_back(*p);
1702 return p->value.second;
1704 return result.first->value.second;
1715 template <
bool maybe_multi,
bool maybe_map,
class>
1720 typename cont_type::insert_commit_data d;
1722 m_cont.insert_check(key,
std::cref(m_config.key_compare()), d));
1725 element*
const p(new_element(
1726 std::piecewise_construct,
1729 m_cont.insert_commit(*p, d);
1730 chronological.list.push_back(*p);
1731 return p->value.second;
1733 return result.first->value.second;
1750 for (
auto iter(chronological.list.begin());
1751 iter != chronological.list.end();)
1752 delete_element(&*iter++);
1753 chronological.list.clear();
1766 template <
bool maybe_multi>
1772 typename cont_type::insert_commit_data d;
1773 auto const result(m_cont.insert_check(
1774 extract(value),
std::cref(m_config.key_compare()), d));
1777 element*
const p(new_element(value));
1778 auto const iter(m_cont.insert_commit(*p, d));
1779 chronological.list.push_back(*p);
1794 template <
bool maybe_multi>
1797 insert(value_type
const& value) ->
1801 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1802 element*
const p(new_element(value));
1803 chronological.list.push_back(*p);
1804 auto const iter(m_cont.insert_before(before, *p));
1805 return iterator(iter);
1817 template <
bool maybe_multi,
bool maybe_map>
1821 enable_if<!maybe_multi && !maybe_map, std::pair<iterator, bool>>::type
1823 typename cont_type::insert_commit_data d;
1824 auto const result(m_cont.insert_check(
1825 extract(value),
std::cref(m_config.key_compare()), d));
1828 element*
const p(new_element(std::move(value)));
1829 auto const iter(m_cont.insert_commit(*p, d));
1830 chronological.list.push_back(*p);
1845 template <
bool maybe_multi,
bool maybe_map>
1848 insert(value_type&& value) ->
1852 m_cont.upper_bound(extract(value),
std::cref(m_config.key_compare())));
1853 element*
const p(new_element(std::move(value)));
1854 chronological.list.push_back(*p);
1855 auto const iter(m_cont.insert_before(before, *p));
1856 return iterator(iter);
1870 template <
bool maybe_multi>
1876 typename cont_type::insert_commit_data d;
1877 auto const result(m_cont.insert_check(
1878 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1881 element*
const p(new_element(value));
1882 auto const iter(m_cont.insert_commit(*p, d));
1883 chronological.list.push_back(*p);
1898 template <
bool maybe_multi>
1904 typename cont_type::insert_commit_data d;
1905 auto const result(m_cont.insert_check(
1906 hint.iterator(), extract(value),
std::cref(m_config.key_compare()), d));
1909 element*
const p(new_element(std::move(value)));
1910 auto const iter(m_cont.insert_commit(*p, d));
1911 chronological.list.push_back(*p);
1926 template <
bool maybe_multi,
class... Args>
1934 element*
const p(new_element(std::forward<Args>(args)...));
1935 typename cont_type::insert_commit_data d;
1936 auto const result(m_cont.insert_check(
1937 extract(p->value),
std::cref(m_config.key_compare()), d));
1940 auto const iter(m_cont.insert_commit(*p, d));
1941 chronological.list.push_back(*p);
1957 template <
bool maybe_multi,
class... Args>
1963 element*
const p(new_element(std::forward<Args>(args)...));
1964 auto const before(m_cont.upper_bound(
1965 extract(p->value),
std::cref(m_config.key_compare())));
1966 chronological.list.push_back(*p);
1967 auto const iter(m_cont.insert_before(before, *p));
1968 return iterator(iter);
1980 template <
bool maybe_multi,
class... Args>
1988 element*
const p(new_element(std::forward<Args>(args)...));
1989 typename cont_type::insert_commit_data d;
1990 auto const result(m_cont.insert_check(
1997 auto const iter(m_cont.insert_commit(*p, d));
1998 chronological.list.push_back(*p);
2013 template <
bool is_const,
class Iterator,
class Base,
class>
2018 unlink_and_delete_element(&*((pos++).
iterator()));
2031 template <
bool is_const,
class Iterator,
class Base,
class>
2038 for (; first != last;)
2039 unlink_and_delete_element(&*((first++).
iterator()));
2058 auto iter(m_cont.find(k,
std::cref(m_config.key_compare())));
2059 if (iter == m_cont.end())
2065 bool const done(m_config(*p, extract(iter->value)));
2066 unlink_and_delete_element(p);
2087 std::swap(chronological, other.chronological);
2106 auto const now(clock().now());
2108 auto const range(equal_range(k));
2109 for (
auto iter : range)
2131 class OtherDuration,
2132 class OtherAllocator>
2142 OtherAllocator>
const& other)
const
2152 if (size() != other.size())
2161 value_type const& lhs,
typename Other::value_type
const& rhs) {
2162 return eq(extract(lhs), other.extract(rhs));
2176 template <
bool is_const,
class Iterator,
class Base,
class>
2185 chronological.list.erase(chronological.list.iterator_to(e));
2186 chronological.list.push_back(e);
2197 template <
bool maybe_propagate>
2202 std::swap(m_config.key_compare(), other.m_config.key_compare());
2203 std::swap(m_config.alloc(), other.m_config.alloc());
2204 std::swap(m_config.clock, other.m_config.clock);
2215 template <
bool maybe_propagate>
2220 std::swap(m_config.key_compare(), other.m_config.key_compare());
2221 std::swap(m_config.clock, other.m_config.clock);
2275 Allocator>& rhs) noexcept
2304 auto const expired(c.clock().now() - age);
2305 for (
auto iter(c.chronological.cbegin());
2306 iter != c.chronological.cend() && iter.when() <= expired;)
2308 iter = c.erase(iter);