Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef PHAL_TYPE_KEY_MAP_HPP
00007 #define PHAL_TYPE_KEY_MAP_HPP
00008
00009 #include "Teuchos_Array.hpp"
00010 #include "Teuchos_any.hpp"
00011
00012 #include "boost/mpl/vector.hpp"
00013 #include "boost/mpl/pair.hpp"
00014 #include "boost/mpl/find_if.hpp"
00015 #include "boost/mpl/size.hpp"
00016 #include "boost/mpl/transform.hpp"
00017 #include "boost/mpl/back_inserter.hpp"
00018 #include "boost/mpl/placeholders.hpp"
00019 #include "boost/type_traits.hpp"
00020
00021 namespace PHAL {
00022
00024
00033 template <typename TypeMap>
00034 class TypeKeyMap {
00035
00036 public:
00037
00039 template <typename T>
00040 struct GetObjectTypeAndPos {
00041 typedef typename boost::mpl::find_if<
00042 TypeMap,
00043 boost::is_same<boost::mpl::first<boost::mpl::placeholders::_1>, T >
00044 >::type Iter;
00045 typedef typename boost::mpl::deref<Iter>::type Pair;
00046 typedef typename boost::mpl::second<Pair>::type type;
00047 typedef typename Iter::pos pos;
00048 static const int value = pos::value;
00049 };
00050
00052 template <typename T>
00053 struct GetObjectRefType {
00054 typedef typename GetObjectTypeAndPos<T>::type object_type;
00055 typedef typename boost::add_reference<object_type>::type type;
00056 };
00057
00059 template <typename T>
00060 struct GetObjectConstRefType {
00061 typedef typename GetObjectTypeAndPos<T>::type object_type;
00062 typedef typename boost::add_const<object_type>::type const_type;
00063 typedef typename boost::add_reference<const_type>::type type;
00064 };
00065
00067 typedef Teuchos::Array<Teuchos::any> container;
00068
00070 typedef typename container::iterator iterator;
00071
00073 typedef typename container::const_iterator const_iterator;
00074
00076 TypeKeyMap() : objects(boost::mpl::size<TypeMap>::value) {}
00077
00079 ~TypeKeyMap() {}
00080
00082 template<typename T> typename GetObjectRefType<T>::type
00083 getValue() {
00084 typedef typename GetObjectTypeAndPos<T>::type type;
00085 const int pos = GetObjectTypeAndPos<T>::value;
00086 return Teuchos::any_cast<type>(objects[pos]);
00087 }
00088
00090 template<typename T> typename GetObjectConstRefType<T>::type
00091 getValue() const {
00092 typedef typename GetObjectTypeAndPos<T>::type type;
00093 const int pos = GetObjectTypeAndPos<T>::value;
00094 return Teuchos::any_cast<type>(objects[pos]);
00095 }
00096
00098 template <typename T>
00099 void setValue(typename GetObjectConstRefType<T>::type x) {
00100 const int pos = GetObjectTypeAndPos<T>::value;
00101 objects[pos] = x;
00102 }
00103
00105 iterator begin() { return iterator(objects.begin()); }
00106
00108 const_iterator begin() const { return iterator(objects.begin()); }
00109
00111 iterator end() { return iterator(objects.end()); }
00112
00114 const_iterator end() const { return iterator(objects.end()); }
00115
00116 private:
00117
00119 container objects;
00120
00121 };
00122
00124 template <typename KeySeq, typename ElemSeq>
00125 struct ZipMap {
00126
00127
00128 struct CreatePair {
00129 template <typename T1, typename T2> struct apply {
00130 typedef boost::mpl::pair<T1,T2> type;
00131 };
00132 };
00133
00134 typedef typename
00135 boost::mpl::transform<
00136 KeySeq,
00137 ElemSeq,
00138 CreatePair,
00139 boost::mpl::back_inserter< boost::mpl::vector<> > >::type type;
00140 };
00141
00146 template <typename KeySeq, typename F>
00147 struct CreateLambdaKeyMap {
00148 typedef typename boost::mpl::transform<KeySeq, F>::type ElemSeq;
00149 typedef typename ZipMap<KeySeq,ElemSeq>::type type;
00150 };
00151
00152 }
00153
00154 #endif