blob: cf2634fc4f076c6af6cb96af29aec4e7f4ead40e [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_CONTAINER_H_
21#define MULTI_POLICY_CONTAINER_H_
22
23#include <boost/mpl/inherit_linearly.hpp>
24#include <boost/mpl/at.hpp>
25
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070026namespace ns3 {
27namespace ndn {
28namespace ndnSIM {
29namespace detail {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070030
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080031template<class Base, class Value>
32struct policy_wrap {
33 policy_wrap(Base& base)
34 : value_(base)
35 {
36 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070037 Value value_;
38};
39
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080040template<class Base, class Super /*empy_wrap/previous level*/,
41 class Value /*policy_wrap< element in vector >*/>
42struct inherit_with_base : Super, Value {
43 inherit_with_base(Base& base)
44 : Super(base)
45 , Value(base)
46 {
47 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070048
49 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050 update(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070051 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052 Value::value_.update(item);
53 Super::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070054 }
55
56 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 insert(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070058 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 bool ok = Value::value_.insert(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070060 if (!ok)
61 return false;
62
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 ok = Super::insert(item);
64 if (!ok) {
65 Value::value_.erase(item);
66 return false;
67 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070068 return true;
69 }
70
71 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 lookup(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070073 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 Value::value_.lookup(item);
75 Super::lookup(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070076 }
77
78 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080079 erase(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070080 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080081 Value::value_.erase(item);
82 Super::erase(item);
83 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070084
85 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086 clear()
Alexander Afanasyev78057c32012-07-06 15:18:46 -070087 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088 Value::value_.clear();
89 Super::clear();
Alexander Afanasyev78057c32012-07-06 15:18:46 -070090 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070091};
92
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080093template<class Base>
94struct empty_policy_wrap {
95 empty_policy_wrap(Base& base)
96 {
97 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070098
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099 void
100 update(typename Base::iterator item)
101 {
102 }
103 bool
104 insert(typename Base::iterator item)
105 {
106 return true;
107 }
108 void
109 lookup(typename Base::iterator item)
110 {
111 }
112 void
113 erase(typename Base::iterator item)
114 {
115 }
116 void
117 clear()
118 {
119 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700120};
121
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800122template<class Base, class Vector>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700123struct multi_policy_container
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124 : public boost::mpl::
125 fold<Vector, empty_policy_wrap<Base>,
126 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
127 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
128 typedef typename boost::mpl::
129 fold<Vector, empty_policy_wrap<Base>,
130 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
131 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800132
133 typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
134 typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;
135
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 iterator
137 begin()
138 {
139 return this->get<0>().begin();
140 }
141 const_iterator
142 begin() const
143 {
144 return this->get<0>().begin();
145 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800146
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147 iterator
148 end()
149 {
150 return this->get<0>().end();
151 }
152 const_iterator
153 end() const
154 {
155 return this->get<0>().end();
156 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800157
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 size_t
159 size() const
160 {
161 return this->get<0>().size();
162 }
163
164 multi_policy_container(Base& base)
165 : super(base)
166 {
167 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700168
169 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800170 struct index {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700171 typedef typename boost::mpl::at_c<Vector, N>::type type;
172 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800173
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700174 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800175 T&
176 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700177 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800178 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700179 }
180
181 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800182 const T&
183 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700184 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800185 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700186 }
187
188 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800189 typename boost::mpl::at_c<Vector, N>::type&
190 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700191 {
192 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800193 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700194 }
195
196 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 const typename boost::mpl::at_c<Vector, N>::type&
198 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700199 {
200 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700202 }
203};
204
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700205} // detail
206} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700207} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700208} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700209
210#endif // MULTI_POLICY_CONTAINER_H_