20 #ifndef BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
21 #define BEAST_CONTAINER_DETAIL_AGED_ORDERED_CONTAINER_H_INCLUDED
23 #include <ripple/beast/container/detail/aged_container_iterator.h>
24 #include <ripple/beast/container/detail/aged_associative_container.h>
25 #include <ripple/beast/container/detail/empty_base_optimization.h>
26 #include <ripple/beast/container/aged_container.h>
27 #include <ripple/beast/clock/abstract_clock.h>
28 #include <boost/intrusive/list.hpp>
29 #include <boost/intrusive/set.hpp>
30 #include <boost/version.hpp>
36 #include <ripple/beast/cxx17/type_traits.h>
112 : boost::intrusive::set_base_hook <
113 boost::intrusive::link_mode <
114 boost::intrusive::normal_link>
116 , boost::intrusive::list_base_hook <
117 boost::intrusive::link_mode <
118 boost::intrusive::normal_link>
154 :
value (
std::forward <Args> (args)...)
166 #ifdef _LIBCPP_VERSION
171 #ifndef _LIBCPP_VERSION
179 return this->member() (lhs.first, rhs.first);
204 #ifdef _LIBCPP_VERSION
209 #ifndef _LIBCPP_VERSION
226 bool operator() (K
const& k,
element const& e)
const
232 bool operator() (element
const& e, K
const& k)
const
234 return this->member() (
extract (e.value), k);
238 bool operator() (Key
const& k,
element const& e)
const
243 bool operator() (
element const& e, Key
const& k)
const
264 using list_type =
typename boost::intrusive::make_list <element,
265 boost::intrusive::constant_time_size <false>>::type;
269 typename boost::intrusive::make_multiset <element,
270 boost::intrusive::constant_time_size <true>,
271 boost::intrusive::compare<KeyValueCompare>
273 typename boost::intrusive::make_set <element,
274 boost::intrusive::constant_time_size <true>,
275 boost::intrusive::compare<KeyValueCompare>
280 Allocator>::template rebind_alloc <element>;
305 Allocator
const& alloc_)
314 Allocator
const& alloc_)
325 select_on_container_copy_construction (
366 compare() = std::move (other.compare());
367 alloc() = std::move (other.alloc());
407 template <
class... Args>
419 operator()(element* p)
428 p.
get(),
clock().now(), std::forward <Args> (args)...);
464 ! IsMap,
typename cont_type::iterator>;
466 true,
typename cont_type::iterator>;
468 ! IsMap,
typename cont_type::reverse_iterator>;
470 true,
typename cont_type::reverse_iterator>;
487 ! IsMap,
typename list_type::iterator>;
489 true,
typename list_type::iterator>;
491 ! IsMap,
typename list_type::reverse_iterator>;
493 true,
typename list_type::reverse_iterator>;
558 "must be standard layout");
559 return list.iterator_to (*
reinterpret_cast <element*
>(
567 "must be standard layout");
568 return list.iterator_to (*
reinterpret_cast <element const*
>(
569 reinterpret_cast<uint8_t const*
>(&value)-((
std::size_t)
596 Compare
const& comp);
599 Allocator
const& alloc);
602 Compare
const& comp, Allocator
const& alloc);
604 template <
class InputIt>
607 template <
class InputIt>
609 Compare
const& comp);
611 template <
class InputIt>
613 Allocator
const& alloc);
615 template <
class InputIt>
617 Compare
const& comp, Allocator
const& alloc);
622 Allocator
const& alloc);
627 Allocator
const& alloc);
678 bool maybe_multi = IsMulti,
679 bool maybe_map = IsMap,
686 bool maybe_multi = IsMulti,
687 bool maybe_map = IsMap,
690 at (K
const& k)
const;
693 bool maybe_multi = IsMulti,
694 bool maybe_map = IsMap,
700 bool maybe_multi = IsMulti,
701 bool maybe_map = IsMap,
788 "must be standard layout");
789 return m_cont.iterator_to (*
reinterpret_cast <element*
>(
798 "must be standard layout");
799 return m_cont.iterator_to (*
reinterpret_cast <element const*
>(
800 reinterpret_cast<uint8_t const*
>(&value)-((
std::size_t)
838 template <
bool maybe_multi = IsMulti>
845 template <
bool maybe_multi = IsMulti>
852 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
859 template <
bool maybe_multi = IsMulti,
bool maybe_map = IsMap>
868 template <
bool maybe_multi = IsMulti>
875 template <
bool maybe_multi = IsMulti>
885 template <
bool maybe_multi = IsMulti>
892 template <
bool maybe_multi = IsMulti>
898 return insert (std::move (value));
904 bool maybe_map = IsMap
915 return emplace (std::forward <P> (value));
921 bool maybe_map = IsMap
935 template <
class InputIt>
939 for (; first != last; ++first)
950 template <
bool maybe_multi = IsMulti,
class... Args>
957 template <
bool maybe_multi = IsMulti,
class... Args>
964 template <
bool maybe_multi = IsMulti,
class... Args>
971 template <
bool maybe_multi = IsMulti,
class... Args>
977 return emplace <maybe_multi> (
978 std::forward <Args> (args)...);
982 template <
bool is_const,
class Iterator,
class Base,
989 template <
bool is_const,
class Iterator,
class Base,
997 erase (K
const& k) ->
1006 template <
bool is_const,
class Iterator,
class Base,
1056 auto const r (
m_cont.equal_range (k,
1067 auto const r (
m_cont.equal_range (k,
1142 class OtherDuration,
1143 class OtherAllocator
1148 Key, OtherT, OtherDuration, Compare,
1149 OtherAllocator>
const& other)
const;
1155 class OtherDuration,
1156 class OtherAllocator
1161 Key, OtherT, OtherDuration, Compare,
1162 OtherAllocator>
const& other)
const
1171 class OtherDuration,
1172 class OtherAllocator
1177 Key, OtherT, OtherDuration, Compare,
1178 OtherAllocator>
const& other)
const
1182 cbegin(),
cend(), other.cbegin(), other.cend(), comp);
1189 class OtherDuration,
1190 class OtherAllocator
1195 Key, OtherT, OtherDuration, Compare,
1196 OtherAllocator>
const& other)
const
1198 return ! (other < *
this);
1205 class OtherDuration,
1206 class OtherAllocator
1211 Key, OtherT, OtherDuration, Compare,
1212 OtherAllocator>
const& other)
const
1214 return other < *
this;
1221 class OtherDuration,
1222 class OtherAllocator
1227 Key, OtherT, OtherDuration, Compare,
1228 OtherAllocator>
const& other)
const
1230 return ! (*
this < other);
1235 template <
bool is_const,
class Iterator,
class Base,
1239 is_const, Iterator, Base> pos,
1243 Allocator>::propagate_on_container_swap::value>
1248 Allocator>::propagate_on_container_swap::value>
1259 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1260 class Clock,
class Compare,
class Allocator>
1268 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1269 class Clock,
class Compare,
class Allocator>
1273 Compare
const& comp)
1274 : m_config (clock, comp)
1279 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1280 class Clock,
class Compare,
class Allocator>
1284 Allocator
const& alloc)
1285 : m_config (clock, alloc)
1289 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1290 class Clock,
class Compare,
class Allocator>
1294 Compare
const& comp,
1295 Allocator
const& alloc)
1296 : m_config (clock, comp, alloc)
1301 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1302 class Clock,
class Compare,
class Allocator>
1303 template <
class InputIt>
1309 insert (first, last);
1312 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1313 class Clock,
class Compare,
class Allocator>
1314 template <
class InputIt>
1318 Compare
const& comp)
1319 : m_config (clock, comp)
1322 insert (first, last);
1325 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1326 class Clock,
class Compare,
class Allocator>
1327 template <
class InputIt>
1331 Allocator
const& alloc)
1332 : m_config (clock, alloc)
1334 insert (first, last);
1337 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1338 class Clock,
class Compare,
class Allocator>
1339 template <
class InputIt>
1343 Compare
const& comp,
1344 Allocator
const& alloc)
1345 : m_config (clock, comp, alloc)
1348 insert (first, last);
1351 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1352 class Clock,
class Compare,
class Allocator>
1355 : m_config (other.m_config)
1356 , m_cont (other.m_cont.comp())
1361 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1362 class Clock,
class Compare,
class Allocator>
1365 Allocator
const& alloc)
1366 : m_config (other.m_config, alloc)
1367 , m_cont (other.m_cont.comp())
1372 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1373 class Clock,
class Compare,
class Allocator>
1376 : m_config (
std::move (other.m_config))
1377 , m_cont (
std::move (other.m_cont))
1379 chronological.list = std::move (other.chronological.list);
1382 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1383 class Clock,
class Compare,
class Allocator>
1386 Allocator
const& alloc)
1387 : m_config (
std::move (other.m_config), alloc)
1388 , m_cont (
std::move(other.m_cont.comp()))
1390 insert (other.cbegin(), other.cend());
1394 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1395 class Clock,
class Compare,
class Allocator>
1404 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1405 class Clock,
class Compare,
class Allocator>
1409 Compare
const& comp)
1410 : m_config (clock, comp)
1416 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1417 class Clock,
class Compare,
class Allocator>
1421 Allocator
const& alloc)
1422 : m_config (clock, alloc)
1427 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1428 class Clock,
class Compare,
class Allocator>
1432 Compare
const& comp,
1433 Allocator
const& alloc)
1434 : m_config (clock, comp, alloc)
1440 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1441 class Clock,
class Compare,
class Allocator>
1443 ~aged_ordered_container()
1448 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1449 class Clock,
class Compare,
class Allocator>
1458 this->m_config = other.m_config;
1459 insert (other.begin(), other.end());
1464 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1465 class Clock,
class Compare,
class Allocator>
1472 this->m_config = std::move (other.m_config);
1473 insert (other.begin(), other.end());
1478 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1479 class Clock,
class Compare,
class Allocator>
1492 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1493 class Clock,
class Compare,
class Allocator>
1494 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1499 auto const iter (m_cont.find (k,
1501 if (iter == m_cont.end())
1503 return iter->value.second;
1506 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1507 class Clock,
class Compare,
class Allocator>
1508 template <
class K,
bool maybe_multi,
bool maybe_map,
class>
1511 at (K
const& k)
const
1513 auto const iter (m_cont.find (k,
1515 if (iter == m_cont.end())
1517 return iter->value.second;
1520 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1521 class Clock,
class Compare,
class Allocator>
1522 template <
bool maybe_multi,
bool maybe_map,
class>
1525 operator[] (Key
const& key)
1527 typename cont_type::insert_commit_data d;
1528 auto const result (m_cont.insert_check (key,
1529 std::cref (m_config.key_compare()), d));
1532 element*
const p (new_element (
1535 m_cont.insert_commit (*p, d);
1536 chronological.list.push_back (*p);
1537 return p->value.second;
1539 return result.first->value.second;
1542 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1543 class Clock,
class Compare,
class Allocator>
1544 template <
bool maybe_multi,
bool maybe_map,
class>
1547 operator[] (Key&& key)
1549 typename cont_type::insert_commit_data d;
1550 auto const result (m_cont.insert_check (key,
1551 std::cref (m_config.key_compare()), d));
1554 element*
const p (new_element (
1555 std::piecewise_construct,
1558 m_cont.insert_commit (*p, d);
1559 chronological.list.push_back (*p);
1560 return p->value.second;
1562 return result.first->value.second;
1567 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1568 class Clock,
class Compare,
class Allocator>
1573 for (
auto iter (chronological.list.begin());
1574 iter != chronological.list.end();)
1575 delete_element (&*iter++);
1576 chronological.list.clear();
1581 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1582 class Clock,
class Compare,
class Allocator>
1583 template <
bool maybe_multi>
1590 typename cont_type::insert_commit_data d;
1591 auto const result (m_cont.insert_check (extract (value),
1592 std::cref (m_config.key_compare()), d));
1595 element*
const p (new_element (value));
1596 auto const iter (m_cont.insert_commit (*p, d));
1597 chronological.list.push_back (*p);
1604 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1605 class Clock,
class Compare,
class Allocator>
1606 template <
bool maybe_multi>
1609 insert (value_type
const& value) ->
1613 auto const before (m_cont.upper_bound (
1614 extract (value),
std::cref (m_config.key_compare())));
1615 element*
const p (new_element (value));
1616 chronological.list.push_back (*p);
1617 auto const iter (m_cont.insert_before (before, *p));
1618 return iterator (iter);
1622 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1623 class Clock,
class Compare,
class Allocator>
1624 template <
bool maybe_multi,
bool maybe_map>
1631 typename cont_type::insert_commit_data d;
1632 auto const result (m_cont.insert_check (extract (value),
1633 std::cref (m_config.key_compare()), d));
1636 element*
const p (new_element (std::move (value)));
1637 auto const iter (m_cont.insert_commit (*p, d));
1638 chronological.list.push_back (*p);
1645 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1646 class Clock,
class Compare,
class Allocator>
1647 template <
bool maybe_multi,
bool maybe_map>
1650 insert (value_type&& value) ->
1654 auto const before (m_cont.upper_bound (
1655 extract (value),
std::cref (m_config.key_compare())));
1656 element*
const p (new_element (std::move (value)));
1657 chronological.list.push_back (*p);
1658 auto const iter (m_cont.insert_before (before, *p));
1659 return iterator (iter);
1665 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1666 class Clock,
class Compare,
class Allocator>
1667 template <
bool maybe_multi>
1674 typename cont_type::insert_commit_data d;
1675 auto const result (m_cont.insert_check (hint.iterator(),
1676 extract (value),
std::cref (m_config.key_compare()), d));
1679 element*
const p (new_element (value));
1680 auto const iter (m_cont.insert_commit (*p, d));
1681 chronological.list.push_back (*p);
1688 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1689 class Clock,
class Compare,
class Allocator>
1690 template <
bool maybe_multi>
1697 typename cont_type::insert_commit_data d;
1698 auto const result (m_cont.insert_check (hint.iterator(),
1699 extract (value),
std::cref (m_config.key_compare()), d));
1702 element*
const p (new_element (std::move (value)));
1703 auto const iter (m_cont.insert_commit (*p, d));
1704 chronological.list.push_back (*p);
1711 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1712 class Clock,
class Compare,
class Allocator>
1713 template <
bool maybe_multi,
class... Args>
1716 emplace (Args&&... args) ->
1722 element*
const p (new_element (
1723 std::forward <Args> (args)...));
1724 typename cont_type::insert_commit_data d;
1725 auto const result (m_cont.insert_check (extract (p->value),
1726 std::cref (m_config.key_compare()), d));
1729 auto const iter (m_cont.insert_commit (*p, d));
1730 chronological.list.push_back (*p);
1738 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1739 class Clock,
class Compare,
class Allocator>
1740 template <
bool maybe_multi,
class... Args>
1743 emplace (Args&&... args) ->
1747 element*
const p (new_element (
1748 std::forward <Args> (args)...));
1749 auto const before (m_cont.upper_bound (extract (p->value),
1751 chronological.list.push_back (*p);
1752 auto const iter (m_cont.insert_before (before, *p));
1753 return iterator (iter);
1757 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1758 class Clock,
class Compare,
class Allocator>
1759 template <
bool maybe_multi,
class... Args>
1768 element*
const p (new_element (
1769 std::forward <Args> (args)...));
1770 typename cont_type::insert_commit_data d;
1771 auto const result (m_cont.insert_check (hint.iterator(),
1772 extract (p->value),
std::cref (m_config.key_compare()), d));
1775 auto const iter (m_cont.insert_commit (*p, d));
1776 chronological.list.push_back (*p);
1783 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1784 class Clock,
class Compare,
class Allocator>
1785 template <
bool is_const,
class Iterator,
class Base,
class>
1790 unlink_and_delete_element(&*((pos++).
iterator()));
1792 false, Iterator, Base> (pos.
iterator());
1795 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1796 class Clock,
class Compare,
class Allocator>
1797 template <
bool is_const,
class Iterator,
class Base,
class>
1803 for (; first != last;)
1804 unlink_and_delete_element(&*((first++).
iterator()));
1807 false, Iterator, Base> (first.
iterator());
1810 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1811 class Clock,
class Compare,
class Allocator>
1815 erase (K
const& k) ->
1818 auto iter (m_cont.find (k,
1820 if (iter == m_cont.end())
1827 m_config (*p, extract (iter->value)));
1828 unlink_and_delete_element (p);
1836 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1837 class Clock,
class Compare,
class Allocator>
1843 std::swap (chronological, other.chronological);
1849 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1850 class Clock,
class Compare,
class Allocator>
1854 touch (K
const& k) ->
1857 auto const now (clock().now());
1859 auto const range (equal_range (k));
1860 for (
auto iter : range)
1870 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1871 class Clock,
class Compare,
class Allocator>
1872 template <
bool OtherIsMulti,
bool OtherIsMap,
1873 class OtherT,
class OtherDuration,
class OtherAllocator>
1878 Key, OtherT, OtherDuration, Compare,
1879 OtherAllocator>
const& other)
const
1882 Key, OtherT, OtherDuration, Compare,
1884 if (size() != other.size())
1887 return std::equal (cbegin(), cend(), other.cbegin(), other.cend(),
1889 typename Other::value_type
const& rhs)
1891 return eq (extract (lhs), other.extract (rhs));
1897 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1898 class Clock,
class Compare,
class Allocator>
1899 template <
bool is_const,
class Iterator,
class Base,
class>
1903 is_const, Iterator, Base> pos,
1906 auto& e (*pos.iterator());
1908 chronological.list.erase (chronological.list.iterator_to (e));
1909 chronological.list.push_back (e);
1912 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1913 class Clock,
class Compare,
class Allocator>
1914 template <
bool maybe_propagate>
1919 std::swap (m_config.key_compare(), other.m_config.key_compare());
1920 std::swap (m_config.alloc(), other.m_config.alloc());
1921 std::swap (m_config.clock, other.m_config.clock);
1924 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1925 class Clock,
class Compare,
class Allocator>
1926 template <
bool maybe_propagate>
1931 std::swap (m_config.key_compare(), other.m_config.key_compare());
1932 std::swap (m_config.clock, other.m_config.clock);
1939 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1940 class Clock,
class Compare,
class Allocator>
1942 IsMulti, IsMap, Key, T, Clock, Compare, Allocator>>
1950 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1951 class Clock,
class Compare,
class Allocator>
1954 Key, T, Clock, Compare, Allocator>& lhs,
1956 Key, T, Clock, Compare, Allocator>& rhs) noexcept
1962 template <
bool IsMulti,
bool IsMap,
class Key,
class T,
1963 class Clock,
class Compare,
class Allocator,
1964 class Rep,
class Period>
1966 IsMulti, IsMap, Key, T, Clock, Compare, Allocator>& c,
1970 auto const expired (c.clock().now() - age);
1971 for (
auto iter (c.chronological.cbegin());
1972 iter != c.chronological.cend() &&
1973 iter.when() <= expired;)
1975 iter = c.erase (iter);