blob: 170f691ea123f60f2023ef1c0107d30b2f469747 [file] [log] [blame]
Alexander Afanasyev30cb1172012-07-06 10:47:39 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
21#ifndef MULTI_POLICY_H_
22#define MULTI_POLICY_H_
23
Alexander Afanasyev0c395372014-12-20 15:54:02 -080024#include "detail/multi-type-container.hpp"
25#include "detail/multi-policy-container.hpp"
26#include "detail/functor-hook.hpp"
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070027
28#include <boost/mpl/size.hpp>
29#include <boost/mpl/at.hpp>
30#include <boost/mpl/range_c.hpp>
31#include <boost/mpl/transform.hpp>
32#include <boost/mpl/back_inserter.hpp>
33#include <boost/mpl/vector.hpp>
Alexander Afanasyev8566f452012-12-10 15:21:51 -080034#include <boost/mpl/for_each.hpp>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070035
36#include <boost/intrusive/options.hpp>
37
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070038namespace ns3 {
39namespace ndn {
40namespace ndnSIM {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070041
42template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080043struct multi_policy_traits {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070044 typedef Policies policy_traits;
45
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046 struct getHook {
47 template<class Item>
48 struct apply {
49 typedef typename Item::policy_hook_type type;
50 };
51 };
52 typedef detail::multi_type_container<
53 typename boost::mpl::transform1<policy_traits, getHook>::type> policy_hook_type;
54
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070055 template<class Container>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056 struct container_hook {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070057 typedef policy_hook_type type;
58 };
59
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080060 template<class Base, class Container, class Hook>
61 struct policy {
62 typedef boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>
63 policies_range;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070064
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080065 struct getPolicy {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070066 template<class Number>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067 struct apply {
68 typedef typename boost::mpl::at_c<policy_traits, Number::value>::type::
69 template policy<Base, Container,
70 boost::intrusive::function_hook<detail::FunctorHook<Hook, Container,
71 Number::value>>>::type
72 type;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070073 };
74 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080075
76 typedef typename boost::mpl::transform1<policies_range, getPolicy,
77 boost::mpl::back_inserter<boost::mpl::vector0<>>>::type
78 policies;
79
80 typedef detail::multi_policy_container<Base, policies> policy_container;
81
82 class type : public policy_container {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070083 public:
Alexander Afanasyev69786112012-12-13 11:53:36 -080084 typedef policy policy_base; // to get access to get_time methods from outside
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070085 typedef Container parent_trie;
86
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 type(Base& base)
88 : policy_container(base)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070089 {
90 }
91
92 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080093 update(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070094 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095 policy_container::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070096 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080097
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070098 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099 insert(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700100 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800101 return policy_container::insert(item);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700102 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800103
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104 inline void
105 lookup(typename parent_trie::iterator item)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800106 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800107 policy_container::lookup(item);
108 }
109
110 inline void
111 erase(typename parent_trie::iterator item)
112 {
113 policy_container::erase(item);
114 }
115
116 inline void
117 clear()
118 {
119 policy_container::clear();
120 }
121
122 struct max_size_setter {
123 max_size_setter(policy_container& container, size_t size)
124 : m_container(container)
125 , m_size(size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800126 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127 }
128
129 template<typename U>
130 void
131 operator()(U index)
132 {
133 m_container.template get<U::value>().set_max_size(m_size);
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800134 }
135
136 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800137 policy_container& m_container;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800138 size_t m_size;
139 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800141 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 set_max_size(size_t max_size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800143 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144 boost::mpl::for_each<boost::mpl::range_c<int, 0,
145 boost::mpl::size<policy_traits>::type::value>>(
146 max_size_setter(*this, max_size));
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800147 }
148
149 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150 get_max_size() const
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800151 {
152 // as max size should be the same everywhere, get the value from the first available policy
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153 return policy_container::template get<0>().get_max_size();
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800154 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700155 };
156 };
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800157
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 struct name_getter {
159 name_getter(std::string& name)
160 : m_name(name)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800161 {
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800162 }
163
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164 template<typename U>
165 void
166 operator()(U index)
167 {
168 if (!m_name.empty())
169 m_name += "::";
170 m_name += boost::mpl::at_c<policy_traits, U::value>::type::GetName();
171 }
172
173 std::string& m_name;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800174 };
175
176 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 static std::string
178 GetName()
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800179 {
180 // combine names of all internal policies
181 std::string name;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800182 boost::mpl::for_each<boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>>(
183 name_getter(name));
184
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800185 return name;
186 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700187};
188
189} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700190} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700191} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700192
193#endif // MULTI_POLICY_H_