diff options
author | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
commit | 420d2ef464d4a741028e132e662d5626806a41f5 (patch) | |
tree | 1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/property_list.hpp |
Diffstat (limited to 'core/property_list.hpp')
-rw-r--r-- | core/property_list.hpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/core/property_list.hpp b/core/property_list.hpp new file mode 100644 index 0000000..3fd5ee9 --- /dev/null +++ b/core/property_list.hpp @@ -0,0 +1,94 @@ +#ifndef RAA4DT8yVWXBMqy1rxYiM12MKFA +#define RAA4DT8yVWXBMqy1rxYiM12MKFA + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/empty.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/list.hpp> +#include <boost/mpl/logical.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/pop_front.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include "property_instance.hpp" +#include "template_helpers.hpp" + +namespace PLImpl { + + using namespace boost::mpl; + + // forward decls + template <typename Haystack, typename Needle> struct PL_Contains; + + + /// PL - Property List + + // template <typename Head, bool doWriteResults, typename Tail> + template <typename List> + struct PL { + // compile time data structure (types) + typedef typename front<List>::type head_t; + typedef typename pop_front<List>::type tail_t; + + typedef typename head_t::first prop_t; + typedef typename head_t::second doWriteResult_t; + typedef typename if_<empty<tail_t>, + PL<Void>, + PL<tail_t> + >::type next_t; + + typedef PropertyInstance<prop_t, doWriteResult_t::value > data_t; + + // access methods + // template params: + // - PropComp: the list of all properties + // - Action: the action class to call + template<typename PropComp, typename Action> + inline typename Action::result_t call(PropComp &pc, Action &action) { + typename Action::template local_state_t<prop_t, doWriteResult_t::value> state; + action.pre(pc, data, state); + tail.call<PropComp, Action>(pc, action); + action.post(pc, data, state); + return action.result; + } + + // data members + data_t data; + next_t tail; + + // integrity checks: + // 1. each property may be used only once + BOOST_MPL_ASSERT(( not_< PL_Contains< next_t, prop_t > > )); + // TODO (beauty): dependencies (once they are implemented anywhere) + }; + + // the empty tail + template<> + struct PL<Void> { + typedef Void prop_t; + typedef PL<Void> tail_t; + typedef Void data_t; + + template<typename PropComp, typename Action> + inline typename Action::result_t call(PropComp &pc, Action &action) { + return typename Action::result_t(); + } + }; + + /// PL Template Helpers + template <typename Haystack, typename Needle> + struct PL_Contains : boost::mpl::or_< + boost::is_same<typename Haystack::prop_t, Needle>, + PL_Contains<typename Haystack::next_t, Needle> + > { }; + + template <typename Needle> + struct PL_Contains<PL<Void>, Needle> : boost::mpl::false_ { }; + +}; + +using PLImpl::PL; +using PLImpl::PL_Contains; + +#endif // RAA4DT8yVWXBMqy1rxYiM12MKFA |