blob: 5c3450b665582c972d40c477c3fb4e49392702c4 [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
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -080023/// @cond include_hidden
24
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070025#include <boost/mpl/inherit_linearly.hpp>
26#include <boost/mpl/at.hpp>
27
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070028namespace ns3 {
29namespace ndn {
30namespace ndnSIM {
31namespace detail {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070032
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080033template<class Base, class Value>
34struct policy_wrap {
35 policy_wrap(Base& base)
36 : value_(base)
37 {
38 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070039 Value value_;
40};
41
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042template<class Base, class Super /*empy_wrap/previous level*/,
43 class Value /*policy_wrap< element in vector >*/>
44struct inherit_with_base : Super, Value {
45 inherit_with_base(Base& base)
46 : Super(base)
47 , Value(base)
48 {
49 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070050
51 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052 update(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070053 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080054 Value::value_.update(item);
55 Super::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070056 }
57
58 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080059 insert(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070060 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061 bool ok = Value::value_.insert(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070062 if (!ok)
63 return false;
64
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080065 ok = Super::insert(item);
66 if (!ok) {
67 Value::value_.erase(item);
68 return false;
69 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070070 return true;
71 }
72
73 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 lookup(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070075 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076 Value::value_.lookup(item);
77 Super::lookup(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070078 }
79
80 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080081 erase(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070082 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080083 Value::value_.erase(item);
84 Super::erase(item);
85 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070086
87 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088 clear()
Alexander Afanasyev78057c32012-07-06 15:18:46 -070089 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090 Value::value_.clear();
91 Super::clear();
Alexander Afanasyev78057c32012-07-06 15:18:46 -070092 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070093};
94
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095template<class Base>
96struct empty_policy_wrap {
97 empty_policy_wrap(Base& base)
98 {
99 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700100
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800101 void
102 update(typename Base::iterator item)
103 {
104 }
105 bool
106 insert(typename Base::iterator item)
107 {
108 return true;
109 }
110 void
111 lookup(typename Base::iterator item)
112 {
113 }
114 void
115 erase(typename Base::iterator item)
116 {
117 }
118 void
119 clear()
120 {
121 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700122};
123
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124template<class Base, class Vector>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700125struct multi_policy_container
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 : public boost::mpl::
127 fold<Vector, empty_policy_wrap<Base>,
128 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
129 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
130 typedef typename boost::mpl::
131 fold<Vector, empty_policy_wrap<Base>,
132 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
133 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800134
135 typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
136 typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;
137
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800138 iterator
139 begin()
140 {
141 return this->get<0>().begin();
142 }
143 const_iterator
144 begin() const
145 {
146 return this->get<0>().begin();
147 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800148
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 iterator
150 end()
151 {
152 return this->get<0>().end();
153 }
154 const_iterator
155 end() const
156 {
157 return this->get<0>().end();
158 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800159
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 size_t
161 size() const
162 {
163 return this->get<0>().size();
164 }
165
166 multi_policy_container(Base& base)
167 : super(base)
168 {
169 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700170
171 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800172 struct index {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700173 typedef typename boost::mpl::at_c<Vector, N>::type type;
174 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800175
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700176 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 T&
178 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700179 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800180 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700181 }
182
183 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800184 const T&
185 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700186 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800187 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700188 }
189
190 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800191 typename boost::mpl::at_c<Vector, N>::type&
192 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700193 {
194 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700196 }
197
198 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199 const typename boost::mpl::at_c<Vector, N>::type&
200 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700201 {
202 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700204 }
205};
206
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700207} // detail
208} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700209} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700210} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700211
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800212/// @endcond
213
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700214#endif // MULTI_POLICY_CONTAINER_H_