blob: 534499f3ad8eb7d1fc83c99756d226bcd02e1891 [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
Alexander Afanasyev0c395372014-12-20 15:54:02 -080023#include "detail/multi-type-container.hpp"
24#include "detail/multi-policy-container.hpp"
25#include "detail/functor-hook.hpp"
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070026
27#include <boost/mpl/size.hpp>
28#include <boost/mpl/at.hpp>
29#include <boost/mpl/range_c.hpp>
30#include <boost/mpl/transform.hpp>
31#include <boost/mpl/back_inserter.hpp>
32#include <boost/mpl/vector.hpp>
Alexander Afanasyev8566f452012-12-10 15:21:51 -080033#include <boost/mpl/for_each.hpp>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070034
35#include <boost/intrusive/options.hpp>
36
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070037namespace ns3 {
38namespace ndn {
39namespace ndnSIM {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070040
41template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042struct multi_policy_traits {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070043 typedef Policies policy_traits;
44
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045 struct getHook {
46 template<class Item>
47 struct apply {
48 typedef typename Item::policy_hook_type type;
49 };
50 };
51 typedef detail::multi_type_container<
52 typename boost::mpl::transform1<policy_traits, getHook>::type> policy_hook_type;
53
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070054 template<class Container>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055 struct container_hook {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070056 typedef policy_hook_type type;
57 };
58
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 template<class Base, class Container, class Hook>
60 struct policy {
61 typedef boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>
62 policies_range;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070063
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064 struct getPolicy {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070065 template<class Number>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 struct apply {
67 typedef typename boost::mpl::at_c<policy_traits, Number::value>::type::
68 template policy<Base, Container,
69 boost::intrusive::function_hook<detail::FunctorHook<Hook, Container,
70 Number::value>>>::type
71 type;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070072 };
73 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074
75 typedef typename boost::mpl::transform1<policies_range, getPolicy,
76 boost::mpl::back_inserter<boost::mpl::vector0<>>>::type
77 policies;
78
79 typedef detail::multi_policy_container<Base, policies> policy_container;
80
81 class type : public policy_container {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070082 public:
Alexander Afanasyev69786112012-12-13 11:53:36 -080083 typedef policy policy_base; // to get access to get_time methods from outside
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070084 typedef Container parent_trie;
85
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086 type(Base& base)
87 : policy_container(base)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070088 {
89 }
90
91 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092 update(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070093 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 policy_container::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070095 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070097 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098 insert(typename parent_trie::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070099 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 return policy_container::insert(item);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700101 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800102
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103 inline void
104 lookup(typename parent_trie::iterator item)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800105 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106 policy_container::lookup(item);
107 }
108
109 inline void
110 erase(typename parent_trie::iterator item)
111 {
112 policy_container::erase(item);
113 }
114
115 inline void
116 clear()
117 {
118 policy_container::clear();
119 }
120
121 struct max_size_setter {
122 max_size_setter(policy_container& container, size_t size)
123 : m_container(container)
124 , m_size(size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800125 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 }
127
128 template<typename U>
129 void
130 operator()(U index)
131 {
132 m_container.template get<U::value>().set_max_size(m_size);
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800133 }
134
135 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 policy_container& m_container;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800137 size_t m_size;
138 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800140 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141 set_max_size(size_t max_size)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800142 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143 boost::mpl::for_each<boost::mpl::range_c<int, 0,
144 boost::mpl::size<policy_traits>::type::value>>(
145 max_size_setter(*this, max_size));
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800146 }
147
148 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 get_max_size() const
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800150 {
151 // as max size should be the same everywhere, get the value from the first available policy
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 return policy_container::template get<0>().get_max_size();
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800153 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700154 };
155 };
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800156
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800157 struct name_getter {
158 name_getter(std::string& name)
159 : m_name(name)
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800160 {
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800161 }
162
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800163 template<typename U>
164 void
165 operator()(U index)
166 {
167 if (!m_name.empty())
168 m_name += "::";
169 m_name += boost::mpl::at_c<policy_traits, U::value>::type::GetName();
170 }
171
172 std::string& m_name;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800173 };
174
175 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800176 static std::string
177 GetName()
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800178 {
179 // combine names of all internal policies
180 std::string name;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800181 boost::mpl::for_each<boost::mpl::range_c<int, 0, boost::mpl::size<policy_traits>::type::value>>(
182 name_getter(name));
183
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800184 return name;
185 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700186};
187
188} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700189} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700190} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700191
192#endif // MULTI_POLICY_H_