blob: 00bfbf178cc54a2cc0789000267f2e398367a4d3 [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) 2011 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_CONTAINER_H_
22#define MULTI_POLICY_CONTAINER_H_
23
24#include <boost/mpl/inherit_linearly.hpp>
25#include <boost/mpl/at.hpp>
26
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070027namespace ns3 {
28namespace ndn {
29namespace ndnSIM {
30namespace detail {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070031
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080032template<class Base, class Value>
33struct policy_wrap {
34 policy_wrap(Base& base)
35 : value_(base)
36 {
37 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070038 Value value_;
39};
40
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080041template<class Base, class Super /*empy_wrap/previous level*/,
42 class Value /*policy_wrap< element in vector >*/>
43struct inherit_with_base : Super, Value {
44 inherit_with_base(Base& base)
45 : Super(base)
46 , Value(base)
47 {
48 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070049
50 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080051 update(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070052 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080053 Value::value_.update(item);
54 Super::update(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070055 }
56
57 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080058 insert(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070059 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080060 bool ok = Value::value_.insert(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070061 if (!ok)
62 return false;
63
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064 ok = Super::insert(item);
65 if (!ok) {
66 Value::value_.erase(item);
67 return false;
68 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070069 return true;
70 }
71
72 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 lookup(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070074 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080075 Value::value_.lookup(item);
76 Super::lookup(item);
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070077 }
78
79 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080080 erase(typename Base::iterator item)
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070081 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 Value::value_.erase(item);
83 Super::erase(item);
84 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070085
86 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 clear()
Alexander Afanasyev78057c32012-07-06 15:18:46 -070088 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080089 Value::value_.clear();
90 Super::clear();
Alexander Afanasyev78057c32012-07-06 15:18:46 -070091 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070092};
93
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094template<class Base>
95struct empty_policy_wrap {
96 empty_policy_wrap(Base& base)
97 {
98 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070099
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 void
101 update(typename Base::iterator item)
102 {
103 }
104 bool
105 insert(typename Base::iterator item)
106 {
107 return true;
108 }
109 void
110 lookup(typename Base::iterator item)
111 {
112 }
113 void
114 erase(typename Base::iterator item)
115 {
116 }
117 void
118 clear()
119 {
120 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700121};
122
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123template<class Base, class Vector>
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700124struct multi_policy_container
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125 : public boost::mpl::
126 fold<Vector, empty_policy_wrap<Base>,
127 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
128 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
129 typedef typename boost::mpl::
130 fold<Vector, empty_policy_wrap<Base>,
131 inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
132 policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800133
134 typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
135 typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;
136
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800137 iterator
138 begin()
139 {
140 return this->get<0>().begin();
141 }
142 const_iterator
143 begin() const
144 {
145 return this->get<0>().begin();
146 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800147
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148 iterator
149 end()
150 {
151 return this->get<0>().end();
152 }
153 const_iterator
154 end() const
155 {
156 return this->get<0>().end();
157 }
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800158
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159 size_t
160 size() const
161 {
162 return this->get<0>().size();
163 }
164
165 multi_policy_container(Base& base)
166 : super(base)
167 {
168 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700169
170 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800171 struct index {
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700172 typedef typename boost::mpl::at_c<Vector, N>::type type;
173 };
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800174
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700175 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800176 T&
177 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700178 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800179 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700180 }
181
182 template<class T>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183 const T&
184 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700185 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800186 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700187 }
188
189 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 typename boost::mpl::at_c<Vector, N>::type&
191 get()
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700192 {
193 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800194 return static_cast<policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700195 }
196
197 template<int N>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800198 const typename boost::mpl::at_c<Vector, N>::type&
199 get() const
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700200 {
201 typedef typename boost::mpl::at_c<Vector, N>::type T;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 return static_cast<const policy_wrap<Base, T>&>(*this).value_;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700203 }
204};
205
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700206} // detail
207} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700208} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700209} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700210
211#endif // MULTI_POLICY_CONTAINER_H_