88#include < boost/multi_index/sequenced_index.hpp>
99#include < boost/multi_index_container.hpp>
1010
11- #include < boost/mpl/joint_view.hpp>
12- #include < boost/mpl/list.hpp>
13-
1411#include < cstddef>
12+ #include < tuple>
1513#include < utility>
1614
1715USERVER_NAMESPACE_BEGIN
1816
1917namespace multi_index_lru {
2018
19+ namespace impl {
20+ template <typename T, typename = std::void_t <>>
21+ inline constexpr bool is_mpl_na = false ;
22+
23+ template <typename T>
24+ inline constexpr bool is_mpl_na<T, std::void_t <decltype (std::declval<T>().~na ())>> = true ;
25+
26+ template <typename ... Indices>
27+ struct lazy_add_seq {
28+ using type = boost::multi_index::indexed_by<boost::multi_index::sequenced<>, Indices...>;
29+ };
30+
31+ template <typename ... Indices>
32+ struct lazy_add_seq_no_last {
33+ private:
34+ template <std::size_t ... I>
35+ static auto makeWithoutLast (std::index_sequence<I...>) {
36+ using Tuple = std::tuple<Indices...>;
37+ return boost::multi_index::indexed_by<boost::multi_index::sequenced<>, std::tuple_element_t <I, Tuple>...>{};
38+ }
39+
40+ public:
41+ using type = decltype (makeWithoutLast(std::make_index_sequence<sizeof ...(Indices) - 1 >{}));
42+ };
43+
44+ template <typename IndexList>
45+ struct add_seq_index {};
46+
47+ template <typename ... Indices>
48+ struct add_seq_index <boost::multi_index::indexed_by<Indices...>> {
49+ using LastType = decltype ((Indices{}, ...));
50+
51+ using type = typename std::conditional_t <
52+ is_mpl_na<LastType>,
53+ lazy_add_seq_no_last<Indices...>,
54+ lazy_add_seq<Indices...>>::type;
55+ };
56+
57+ template <typename IndexList>
58+ using add_seq_index_t = typename add_seq_index<IndexList>::type;
59+ } // namespace impl
60+
2161// / @ingroup userver_containers
2262// /
2363// / @brief MultiIndex LRU container
24- template <typename Value, typename IndexSpecifierList, typename Allocator = std::allocator<Value> >
64+ template <typename Value, typename IndexSpecifierList, typename Allocator = std::allocator<Value>>
2565class Container {
2666public:
2767 explicit Container (size_t max_size)
@@ -69,11 +109,11 @@ class Container {
69109 return container_.template get <Tag>().erase (key) > 0 ;
70110 }
71111
72- size_t size () const { return container_.size (); }
112+ std:: size_t size () const { return container_.size (); }
73113 bool empty () const { return container_.empty (); }
74- size_t capacity () const { return max_size_; }
114+ std:: size_t capacity () const { return max_size_; }
75115
76- void set_capacity (size_t new_capacity) {
116+ void set_capacity (std:: size_t new_capacity) {
77117 max_size_ = new_capacity;
78118 auto & seq_index = container_.template get <0 >();
79119 while (container_.size () > max_size_) {
@@ -89,14 +129,12 @@ class Container {
89129 }
90130
91131private:
92- using AdditionalIndices = boost::mpl::list<boost::multi_index::sequenced<> >;
93-
94- using ExtendedIndexSpecifierList = boost::mpl::joint_view<AdditionalIndices, IndexSpecifierList>;
132+ using ExtendedIndexSpecifierList = impl::add_seq_index_t <IndexSpecifierList>;
95133
96134 using BoostContainer = boost::multi_index::multi_index_container<Value, ExtendedIndexSpecifierList, Allocator>;
97135
98136 BoostContainer container_;
99- size_t max_size_;
137+ std:: size_t max_size_;
100138};
101139} // namespace multi_index_lru
102140
0 commit comments