blob: 01c8951278ad8bb562208ba52856928525f92028 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev30cb1172012-07-06 10:47:39 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev30cb1172012-07-06 10:47:39 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070019
20#ifndef MULTI_POLICY_H_
21#define MULTI_POLICY_H_
22
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -080023/// @cond include_hidden
24
Alexander Afanasyev0c395372014-12-20 15:54:02 -080025#include "detail/multi-type-container.hpp"
26#include "detail/multi-policy-container.hpp"
27#include "detail/functor-hook.hpp"
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070028
29#include <boost/mpl/size.hpp>
30#include <boost/mpl/at.hpp>
31#include <boost/mpl/range_c.hpp>
32#include <boost/mpl/transform.hpp>
33#include <boost/mpl/back_inserter.hpp>
34#include <boost/mpl/vector.hpp>
Alexander Afanasyev8566f452012-12-10 15:21:51 -080035#include <boost/mpl/for_each.hpp>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070036
37#include <boost/intrusive/options.hpp>
38
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070039namespace ns3 {
40namespace ndn {
41namespace ndnSIM {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070042
43template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080044struct multi_policy_traits {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070045 typedef Policies policy_traits;
46
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080047 struct getHook {
48 template<class Item>
49 struct apply {
50 typedef typename Item::policy_hook_type type;
51 };
52 };
53 typedef detail::multi_type_container<
54 typename boost::mpl::transform1<policy_traits, getHook>::type> policy_hook_type;
55
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070056 template<class Container>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 struct container_hook {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070058 typedef policy_hook_type type;
59 };
60
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061 template<class Base, class Container, class Hook>
62 struct policy {
63 typedef boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>
64 policies_range;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070065
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 struct getPolicy {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070067 template<class Number>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 struct apply {
69 typedef typename boost::mpl::at_c<policy_traits, Number::value>::type::
70 template policy<Base, Container,
71 boost::intrusive::function_hook<detail::FunctorHook<Hook, Container,
72 Number::value>>>::type
73 type;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070074 };
75 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076
77 typedef typename boost::mpl::transform1<policies_range, getPolicy,
78 boost::mpl::back_inserter<boost::mpl::vector0<>>>::type
79 policies;
80
81 typedef detail::multi_policy_container<Base, policies> policy_container;
82
83 class type : public policy_container {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070084 public:
Alexander Afanasyev69786112012-12-13 11:53:36 -080085 typedef policy policy_base; // to get access to get_time methods from outside
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070086 typedef Container parent_trie;
87
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088 type(Base& base)
89 : policy_container(base)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070090 {
91 }
92
93 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 update(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070095 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096 policy_container::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070097 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070099 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 insert(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700101 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800102 return policy_container::insert(item);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700103 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800104
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 inline void
106 lookup(typename parent_trie::iterator item)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800107 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 policy_container::lookup(item);
109 }
110
111 inline void
112 erase(typename parent_trie::iterator item)
113 {
114 policy_container::erase(item);
115 }
116
117 inline void
118 clear()
119 {
120 policy_container::clear();
121 }
122
123 struct max_size_setter {
124 max_size_setter(policy_container& container, size_t size)
125 : m_container(container)
126 , m_size(size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800127 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 }
129
130 template<typename U>
131 void
132 operator()(U index)
133 {
134 m_container.template get<U::value>().set_max_size(m_size);
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800135 }
136
137 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800138 policy_container& m_container;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800139 size_t m_size;
140 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800142 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143 set_max_size(size_t max_size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800144 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145 boost::mpl::for_each<boost::mpl::range_c<int, 0,
146 boost::mpl::size<policy_traits>::type::value>>(
147 max_size_setter(*this, max_size));
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800148 }
149
150 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 get_max_size() const
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800152 {
153 // as max size should be the same everywhere, get the value from the first available policy
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800154 return policy_container::template get<0>().get_max_size();
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800155 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700156 };
157 };
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800158
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159 struct name_getter {
160 name_getter(std::string& name)
161 : m_name(name)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800162 {
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800163 }
164
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800165 template<typename U>
166 void
167 operator()(U index)
168 {
169 if (!m_name.empty())
170 m_name += "::";
171 m_name += boost::mpl::at_c<policy_traits, U::value>::type::GetName();
172 }
173
174 std::string& m_name;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800175 };
176
177 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800178 static std::string
179 GetName()
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800180 {
181 // combine names of all internal policies
182 std::string name;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183 boost::mpl::for_each<boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>>(
184 name_getter(name));
185
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800186 return name;
187 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700188};
189
190} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700191} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700192} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700193
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800194/// @endcond
195
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700196#endif // MULTI_POLICY_H_