blob: c1251e9522478192a65559c8bd1ae9458bc754bd [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
32template< class Base, class Value >
33struct policy_wrap
34{
35 policy_wrap (Base &base) : value_ (base) { }
36 Value value_;
37};
38
39template< class Base, class Super/*empy_wrap/previous level*/, class Value/*policy_wrap< element in vector >*/ >
40struct inherit_with_base : Super, Value
41{
42 inherit_with_base (Base &base) : Super (base), Value (base) { }
43
44 void
45 update (typename Base::iterator item)
46 {
47 Value::value_.update (item);
48 Super::update (item);
49 }
50
51 bool
52 insert (typename Base::iterator item)
53 {
54 bool ok = Value::value_.insert (item);
55 if (!ok)
56 return false;
57
58 ok = Super::insert (item);
59 if (!ok)
60 {
61 Value::value_.erase (item);
62 return false;
63 }
64 return true;
65 }
66
67 void
68 lookup (typename Base::iterator item)
69 {
70 Value::value_.lookup (item);
71 Super::lookup (item);
72 }
73
74 void
75 erase (typename Base::iterator item)
76 {
77 Value::value_.erase (item);
78 Super::erase (item);
79 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070080
81 void
82 clear ()
83 {
84 Value::value_.clear ();
85 Super::clear ();
86 }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070087};
88
89template< class Base >
90struct empty_policy_wrap
91{
92 empty_policy_wrap (Base &base) { }
93
94 void update (typename Base::iterator item) {}
95 bool insert (typename Base::iterator item) { return true; }
96 void lookup (typename Base::iterator item) {}
97 void erase (typename Base::iterator item) {}
Alexander Afanasyev78057c32012-07-06 15:18:46 -070098 void clear () {}
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070099};
100
101template< class Base, class Vector >
102struct multi_policy_container
103 : public boost::mpl::fold< Vector,
104 empty_policy_wrap<Base>,
105 inherit_with_base<Base,
106 boost::mpl::_1/*empty/previous*/,
107 policy_wrap<Base, boost::mpl::_2>/*element in vector*/>
108 >::type
109{
110 typedef typename boost::mpl::fold< Vector,
111 empty_policy_wrap<Base>,
112 inherit_with_base<Base,
113 boost::mpl::_1/*empty/previous*/,
114 policy_wrap<Base, boost::mpl::_2>/*element in vector*/>
115 >::type super;
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800116
117 typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
118 typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;
119
120 iterator begin () { return this->get<0> ().begin (); }
121 const_iterator begin () const { return this->get<0> ().begin (); }
122
123 iterator end () { return this->get<0> ().end (); }
124 const_iterator end () const { return this->get<0> ().end (); }
125
126 size_t size () const { return this->get<0> ().size (); }
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700127
128 multi_policy_container (Base &base)
129 : super (base)
130 { }
131
132 template<int N>
133 struct index
134 {
135 typedef typename boost::mpl::at_c<Vector, N>::type type;
136 };
137
138 template<class T>
139 T &
140 get ()
141 {
142 return static_cast< policy_wrap<Base, T> &> (*this).value_;
143 }
144
145 template<class T>
146 const T &
147 get () const
148 {
149 return static_cast< const policy_wrap<Base, T> &> (*this).value_;
150 }
151
152 template<int N>
153 typename boost::mpl::at_c<Vector, N>::type &
154 get ()
155 {
156 typedef typename boost::mpl::at_c<Vector, N>::type T;
157 return static_cast< policy_wrap<Base, T> &> (*this).value_;
158 }
159
160 template<int N>
161 const typename boost::mpl::at_c<Vector, N>::type &
162 get () const
163 {
164 typedef typename boost::mpl::at_c<Vector, N>::type T;
165 return static_cast< const policy_wrap<Base, T> &> (*this).value_;
166 }
167};
168
169
170} // detail
171} // ndnSIM
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700172} // ndn
Alexander Afanasyeve77db792012-08-09 11:10:58 -0700173} // ns3
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700174
175#endif // MULTI_POLICY_CONTAINER_H_