Now seems that multi-policy container actually works as it should
diff --git a/examples/trie.cc b/examples/trie.cc
index 1b9fb5a..fb10fc4 100644
--- a/examples/trie.cc
+++ b/examples/trie.cc
@@ -25,8 +25,19 @@
#include "../utils/random-policy.h"
#include "../utils/fifo-policy.h"
#include <boost/intrusive/parent_from_member.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/inherit.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/inherit_linearly.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/vector_c.hpp>
+#include <boost/mpl/clear.hpp>
+#include <boost/mpl/sequence_tag.hpp>
using namespace ns3;
+namespace mpl = boost::mpl;
NS_LOG_COMPONENT_DEFINE ("Trie");
@@ -47,33 +58,189 @@
return os;
}
-template<class Policy1, class Policy2>
-struct multi_policy_hook
+template <class T>
+struct wrap
{
- Policy1 hook1_;
- Policy2 hook2_;
+ T value_;
};
-template<class Base, class Container1, class Container2>
+template< class Vector >
+struct multi_type_container
+ : public mpl::inherit_linearly< Vector, mpl::inherit<wrap<mpl::_2>, mpl::_1 >
+ >::type
+{
+ template<int N>
+ struct index
+ {
+ typedef typename mpl::at_c<Vector, N>::type type;
+ };
+
+ template<class T>
+ T &
+ get ()
+ {
+ return static_cast< wrap<T> &> (*this).value_;
+ }
+
+ template<class T>
+ const T &
+ get () const
+ {
+ return static_cast< const wrap<T> &> (*this).value_;
+ }
+
+ template<int N>
+ typename mpl::at_c<Vector, N>::type &
+ get ()
+ {
+ typedef typename mpl::at_c<Vector, N>::type T;
+ return static_cast< wrap<T> &> (*this).value_;
+ }
+
+ template<int N>
+ const typename mpl::at_c<Vector, N>::type &
+ get () const
+ {
+ typedef typename mpl::at_c<Vector, N>::type T;
+ return static_cast< const wrap<T> &> (*this).value_;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+template< class Base, class Value >
+struct policy_wrap
+{
+ typedef Value value_type;
+
+ policy_wrap (Base &base)
+ : value_ (base)
+ { }
+
+ Value value_;
+};
+
+template< class Base, class Super/*empy_wrap/previous level*/, class Value/*policy_wrap< element in vector >*/ >
+struct inherit_with_base : Super, Value
+{
+ inherit_with_base (Base &base)
+ : Super (base), Value (base)
+ { }
+
+ void
+ update (typename Base::iterator item)
+ {
+ Value::value_.update (item);
+ Super::update (item);
+ }
+
+ bool
+ insert (typename Base::iterator item)
+ {
+ // BOOST_MPL_ASSERT ((boost::is_same<Item,typename Base::iterator>));
+ bool ok = Value::value_.insert (item);
+ if (!ok)
+ return false;
+
+ ok = Super::insert (item);
+ if (!ok)
+ {
+ Value::value_.erase (item);
+ return false;
+ }
+ return true;
+ }
+
+ void
+ lookup (typename Base::iterator item)
+ {
+ Value::value_.lookup (item);
+ Super::lookup (item);
+ }
+
+ void
+ erase (typename Base::iterator item)
+ {
+ Value::value_.erase (item);
+ Super::erase (item);
+ }
+};
+
+template< class Base >
+struct empty_policy_wrap
+{
+ empty_policy_wrap (Base &base) { }
+
+ void update (typename Base::iterator item) {}
+ bool insert (typename Base::iterator item) { return true; }
+ void lookup (typename Base::iterator item) {}
+ void erase (typename Base::iterator item) {}
+};
+
+template< class Base, class Vector >
struct multi_policy_container
+ : public mpl::fold< Vector,
+ empty_policy_wrap<Base>,
+ inherit_with_base<Base,
+ mpl::_1/*empty/previous*/,
+ policy_wrap<Base, mpl::_2>/*element in vector*/>
+ >::type
{
- typedef Container1 nth_container1;
- typedef Container2 nth_container2;
-
+ typedef typename mpl::fold< Vector,
+ empty_policy_wrap<Base>,
+ inherit_with_base<Base,
+ mpl::_1/*empty/previous*/,
+ policy_wrap<Base, mpl::_2>/*element in vector*/>
+ >::type super;
+
multi_policy_container (Base &base)
- : container1_ (base)
- , container2_ (base)
+ : super (base)
+ { }
+
+ template<int N>
+ struct index
{
- }
+ typedef typename mpl::at_c<Vector, N>::type type;
+ };
- nth_container1 container1_;
- nth_container2 container2_;
+ template<class T>
+ T &
+ get ()
+ {
+ return static_cast< policy_wrap<Base, T> &> (*this).value_;
+ }
+
+ template<class T>
+ const T &
+ get () const
+ {
+ return static_cast< const policy_wrap<Base, T> &> (*this).value_;
+ }
+
+ template<int N>
+ typename mpl::at_c<Vector, N>::type &
+ get ()
+ {
+ typedef typename mpl::at_c<Vector, N>::type T;
+ return static_cast< policy_wrap<Base, T> &> (*this).value_;
+ }
+
+ template<int N>
+ const typename mpl::at_c<Vector, N>::type &
+ get () const
+ {
+ typedef typename mpl::at_c<Vector, N>::type T;
+ return static_cast< const policy_wrap<Base, T> &> (*this).value_;
+ }
};
-template<class BaseHook, class ValueType, class HookType>
-struct Functor1
+
+template<class BaseHook, class ValueType, int N>
+struct FunctorHook
{
- typedef HookType hook_type;
+ typedef typename BaseHook::template index<N>::type hook_type;
typedef hook_type* hook_ptr;
typedef const hook_type* const_hook_ptr;
@@ -83,100 +250,67 @@
//Required static functions
static hook_ptr to_hook_ptr (value_type &value)
- { return &value.policy_hook_.hook1_; }
+ { return &value.policy_hook_.template get<N> (); }
static const_hook_ptr to_hook_ptr(const value_type &value)
- { return &value.policy_hook_.hook1_; }
+ { return &value.policy_hook_.template get<N> (); }
static pointer to_value_ptr(hook_ptr n)
{
- return bi::get_parent_from_member<value_type>
- (bi::get_parent_from_member<BaseHook >
- (n, &BaseHook::hook1_)
- , &value_type::policy_hook_
- );
+ return
+ bi::get_parent_from_member<value_type>
+ (static_cast<BaseHook*> (bi::get_parent_from_member< wrap<hook_type> >(n, &wrap<hook_type>::value_)),
+ &value_type::policy_hook_);
}
static const_pointer to_value_ptr(const_hook_ptr n)
{
- return bi::get_parent_from_member<value_type>
- (bi::get_parent_from_member<BaseHook>
- (n, &BaseHook::hook1_)
- , &value_type::policy_hook_
- );
+ return
+ bi::get_parent_from_member<value_type>
+ (static_cast<const BaseHook*> (bi::get_parent_from_member< wrap<hook_type> >(n, &wrap<hook_type>::value_)),
+ &value_type::policy_hook_);
}
};
-template<class BaseHook, class ValueType, class HookType>
-struct Functor2
-{
- typedef HookType hook_type;
- typedef hook_type* hook_ptr;
- typedef const hook_type* const_hook_ptr;
-
- typedef ValueType value_type;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
-
- //Required static functions
- static hook_ptr to_hook_ptr (value_type &value)
- { return &value.policy_hook_.hook2_; }
-
- static const_hook_ptr to_hook_ptr(const value_type &value)
- { return &value.policy_hook_.hook2_; }
-
- static pointer to_value_ptr(hook_ptr n)
- {
- return bi::get_parent_from_member<value_type>
- (bi::get_parent_from_member<BaseHook >
- (n, &BaseHook::hook2_)
- , &value_type::policy_hook_
- );
- }
- static const_pointer to_value_ptr(const_hook_ptr n)
- {
- return bi::get_parent_from_member<value_type>
- (bi::get_parent_from_member<BaseHook>
- (n, &BaseHook::hook2_)
- , &value_type::policy_hook_
- );
- }
-};
-
-
+template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
struct multi_policy_traits
{
- typedef multi_policy_hook< lru_policy_traits::policy_hook_type
- ,
- random_policy_traits::policy_hook_type
- > policy_hook_type;
+ typedef Policies policy_traits;
+ struct getHook
+ {
+ template<class Item>
+ struct apply
+ {
+ typedef typename Item::policy_hook_type type;
+ };
+ };
+
+ typedef multi_type_container< typename mpl::transform1<policy_traits, getHook>::type > policy_hook_type;
+ typedef mpl::range_c<int, 0, mpl::size<policy_traits>::type::value> policies_range;
+
template<class Container>
struct container_hook
{
- struct type
- {
- typedef bi::function_hook< Functor1 <policy_hook_type,
- Container,
- typename lru_policy_traits::policy_hook_type> > hook1;
-
- struct hook2
- {
- typedef bi::function_hook< Functor2 <policy_hook_type,
- Container,
- typename random_policy_traits::policy_hook_type> > hook_type;
-
- static uint32_t& get_order (typename Container::iterator item)
- {
- return item->policy_hook_.hook2_.randomOrder;
- }
-
- static const uint32_t& get_order (typename Container::const_iterator item)
- {
- return item->policy_hook_.hook2_.randomOrder;
- }
- };
-
- };
+ typedef void type;
+ // struct getFunctionHook
+ // {
+ // template<class Number>
+ // struct apply
+ // {
+ // // typedef void type;
+ // typedef bi::function_hook< FunctorHook <policy_hook_type,
+ // Container,
+ // Number::value> > type;
+ // };
+ // };
+
+ // struct type
+ // {
+ // typedef
+ // typename mpl::transform1<policies_range,
+ // getFunctionHook,
+ // mpl::back_inserter< mpl::vector0<> > >::type hooks;
+ // };
};
template<class Base,
@@ -184,12 +318,45 @@
class Hook>
struct policy
{
- typedef multi_policy_container <
- Base,
- typename lru_policy_traits::policy< Base, Container, typename Hook::hook1 >::type
- ,
- typename random_policy_traits::policy< Base, Container, typename Hook::hook2 >::type
- > policy_container;
+ // 1 hooks
+ // 2 actual policies
+
+ // struct getPolicy
+ // {
+ // template<class Item>
+ // struct apply
+ // {
+ // typedef typename Item::template policy<Base,
+ // Container,
+ // typename mpl::at_c<typename Hook::hooks,0>::type >::type type;
+ // };
+ // };
+
+ // typedef typename mpl::transform1<policy_traits, getPolicy>::type policies;
+
+ struct getPolicy
+ {
+ template<class Number>
+ struct apply
+ {
+ typedef
+ typename mpl::at_c<policy_traits, Number::value>::type::
+ template policy<Base,
+ Container,
+ bi::function_hook< FunctorHook <policy_hook_type,
+ Container,
+ Number::value> > >::type
+ type;
+ };
+ };
+
+ typedef
+ typename mpl::transform1<policies_range,
+ getPolicy,
+ mpl::back_inserter< mpl::vector0<> > >::type policies;
+
+
+ typedef multi_policy_container< Base, policies > policy_container;
class type : public policy_container
{
@@ -204,82 +371,64 @@
inline void
update (typename parent_trie::iterator item)
{
- this->container1_.update (item);
- this->container2_.update (item);
+ policy_container::update (item);
}
inline bool
insert (typename parent_trie::iterator item)
{
- bool ok;
- ok = this->container1_.insert (item);
- if (!ok)
- {
- // nothing to undo. just return false
- return false;
- }
-
- ok = this->container2_.insert (item);
- if (!ok)
- {
- // undo and return false
- this->container1_.erase (item);
- return false;
- }
- return true;
+ return policy_container::insert (item);
}
inline void
lookup (typename parent_trie::iterator item)
{
- this->container1_.lookup (item);
- this->container2_.lookup (item);
+ policy_container::lookup (item);
}
inline void
erase (typename parent_trie::iterator item)
{
- this->container1_.erase (item);
- this->container2_.erase (item);
- }
-
- inline typename policy_container::nth_container1 &
- get1 ()
- {
- return this->container1_;
- }
-
- inline typename policy_container::nth_container2 &
- get2 ()
- {
- return this->container2_;
+ policy_container::erase (item);
}
};
};
};
+
int
main (int argc, char *argv[])
{
CommandLine args;
args.Parse (argc, argv);
+
+ // typedef multi_policy_traits<lru_policy_traits> traits;
+ // // traits::policy<traits::hook>
+ // traits::policy<Bla1,Bla2, traits::container_hook<Bla2>::type> x;
typedef trie_with_policy<
ns3::CcnxNameComponents,
smart_pointer_payload_traits<Integer>,
- multi_policy_traits > trie;
+ multi_policy_traits<
+ mpl::vector2<lru_policy_traits,fifo_policy_traits>
+ // mpl::vector1<lru_policy_traits>
+ > > trie;
+ // // multi_policy_traits<lru_policy_traits, random_policy_traits> > trie;
trie x;
- x.getPolicy ().get1 ().set_max_size (10);
- x.getPolicy ().get2 ().set_max_size (3);
+ x.getPolicy ().get<0> ().set_max_size (3);
+ x.getPolicy ().get<1> ().set_max_size (100);
+ // // x.getPolicy ().get<1> ().set_max_size (3);
+ // // // x.getPolicy ().get1 ().set_max_size (10);
+ // // // x.getPolicy ().get2 ().set_max_size (3);
- // x.getTrie ().PrintStat (std::cout);
+ // // // x.getTrie ().PrintStat (std::cout);
ns3::CcnxNameComponents n1,n2,n3,n4;
- // n1("a")("b")("c");
- // n2("a")("b")("d");
- // n3("a")("b")("f");
- // n4("a")("b");
+ // // // n1("a")("b")("c");
+ // // // n2("a")("b")("d");
+ // // // n3("a")("b")("f");
+ // // // n4("a")("b");
n1("a");
n2("b");
@@ -288,10 +437,10 @@
x.insert (n1, ns3::Create<Integer> (1));
x.insert (n2, ns3::Create<Integer> (2));
- x.longest_prefix_match (n1);
+ // // // x.longest_prefix_match (n1);
x.insert (n3, ns3::Create<Integer> (3));
x.insert (n4, ns3::Create<Integer> (4));
- // x.insert (n4, ns3::Create<Integer> (4));
+ x.insert (n4, ns3::Create<Integer> (4));
std::cout << "digraph trie {\n";
std::cout << x.getTrie ();