blob: 739de7b15a21eb9973594d7703fbd0690082cc4c [file] [log] [blame]
Jeff Thompsonfa306642013-06-17 15:06:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#ifndef MULTI_POLICY_H_
12#define MULTI_POLICY_H_
13
14#include "detail/multi-type-container.h"
15#include "detail/multi-policy-container.h"
16#include "detail/functor-hook.h"
17
18#include <boost/mpl/size.hpp>
19#include <boost/mpl/at.hpp>
20#include <boost/mpl/range_c.hpp>
21#include <boost/mpl/transform.hpp>
22#include <boost/mpl/back_inserter.hpp>
23#include <boost/mpl/vector.hpp>
24#include <boost/mpl/for_each.hpp>
25
26#include <boost/intrusive/options.hpp>
27
28namespace ndn {
29namespace trie {
30
31template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
32struct multi_policy_traits
33{
34 typedef Policies policy_traits;
35
36 struct getHook { template<class Item> struct apply { typedef typename Item::policy_hook_type type; }; };
37 typedef detail::multi_type_container< typename boost::mpl::transform1<policy_traits, getHook>::type > policy_hook_type;
38
39 template<class Container>
40 struct container_hook
41 {
42 typedef policy_hook_type type;
43 };
44
45 template<class Base,
46 class Container,
47 class Hook>
48 struct policy
49 {
50 typedef boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value> policies_range;
51
52 struct getPolicy
53 {
54 template<class Number>
55 struct apply
56 {
57 typedef
58 typename boost::mpl::at_c<policy_traits, Number::value>::type::
59 template policy<Base,
60 Container,
61 boost::intrusive::function_hook< detail::FunctorHook <Hook,
62 Container,
63 Number::value> > >::type
64 type;
65 };
66 };
67
68 typedef
69 typename boost::mpl::transform1<policies_range,
70 getPolicy,
71 boost::mpl::back_inserter< boost::mpl::vector0<> > >::type policies;
72
73
74 typedef detail::multi_policy_container< Base, policies > policy_container;
75
76 class type : public policy_container
77 {
78 public:
79 typedef policy policy_base; // to get access to get_time methods from outside
80 typedef Container parent_trie;
81
82 type (Base &base)
83 : policy_container (base)
84 {
85 }
86
87 inline void
88 update (typename parent_trie::iterator item)
89 {
90 policy_container::update (item);
91 }
92
93 inline bool
94 insert (typename parent_trie::iterator item)
95 {
96 return policy_container::insert (item);
97 }
98
99 inline void
100 lookup (typename parent_trie::iterator item)
101 {
102 policy_container::lookup (item);
103 }
104
105 inline void
106 erase (typename parent_trie::iterator item)
107 {
108 policy_container::erase (item);
109 }
110
111 inline void
112 clear ()
113 {
114 policy_container::clear ();
115 }
116
117 struct max_size_setter
118 {
119 max_size_setter (policy_container &container, size_t size) : m_container (container), m_size (size) { }
120
121 template< typename U > void operator() (U index)
122 {
123 m_container.template get<U::value> ().set_max_size (m_size);
124 }
125
126 private:
127 policy_container &m_container;
128 size_t m_size;
129 };
130
131 inline void
132 set_max_size (size_t max_size)
133 {
134 boost::mpl::for_each< boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value> >
135 (max_size_setter (*this, max_size));
136 }
137
138 inline size_t
139 get_max_size () const
140 {
141 // as max size should be the same everywhere, get the value from the first available policy
142 return policy_container::template get<0> ().get_max_size ();
143 }
144
145 };
146 };
147
148
149 struct name_getter
150 {
151 name_getter (std::string &name) : m_name (name) { }
152
153 template< typename U > void operator() (U index)
154 {
155 if (!m_name.empty ())
156 m_name += "::";
157 m_name += boost::mpl::at_c< policy_traits, U::value >::type::GetName ();
158 }
159
160 std::string &m_name;
161 };
162
163 /// @brief Name that can be used to identify the policy (e.g., for logging)
164 static std::string GetName ()
165 {
166 // combine names of all internal policies
167 std::string name;
168 boost::mpl::for_each< boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value> > (name_getter (name));
169
170 return name;
171 }
172};
173
174} // trie
175} // ndn
176
177#endif // MULTI_POLICY_H_