00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __TUPLE_GENERATOR_HH
00018 # define __TUPLE_GENERATOR_HH
00019
00020 # include <tuple>
00021
00022 namespace catsfoot {
00023
00024 namespace details {
00025
00026 template <typename U>
00027 struct tuple_generator_tool {};
00028
00030 template <typename... U>
00031 struct tuple_generator_tool<std::tuple<U...>& >:
00032 public tuple_generator_tool<std::tuple<U...> > {
00033 };
00034
00036 template <typename... U>
00037 struct tuple_generator_tool<const std::tuple<U...>& >:
00038 public tuple_generator_tool<std::tuple<U...> > {
00039 };
00040
00042 template <typename... U>
00043 struct tuple_generator_tool<std::tuple<U...> > {
00044
00045 template <typename... V, typename... Values,
00046 typename = void,
00047 typename = typename std::enable_if
00048 <(sizeof...(V) == sizeof...(Values))>::type>
00049 std::list<std::tuple<U...> >
00050 make_list(std::tuple<V...>&, Values... values...)
00051 const {
00052 return std::list<std::tuple<U...> >
00053 {std::tuple<U...>
00054 {std::forward<Values>(values)...}};
00055 }
00056
00057 template <typename... V, typename... Values,
00058 typename = typename
00059 std::enable_if<(sizeof...(V) > sizeof...(Values))>::type>
00060 std::list<std::tuple<U...> >
00061 make_list(std::tuple<V...>& containers,
00062 Values... values) const
00063 {
00064 std::list<std::tuple<U...> > ret;
00065 typename std::tuple_element<sizeof...(Values),
00066 std::tuple<V...> >::type&
00067 local_container(std::get<sizeof...(Values)>(containers));
00068
00069 for (auto i = local_container.begin();
00070 i != local_container.end();
00071 ++i) {
00072 auto r = make_list(containers, std::forward<Values>(values)...,
00073 typename
00074 std::tuple_element<sizeof...(Values),
00075 std::tuple<U...> >::type(*i));
00076 ret.splice(ret.end(), r);
00077 }
00078 return ret;
00079 }
00080
00081 template <typename Generator>
00082 std::list<std::tuple<U...> >
00083 operator()(Generator& g) const {
00084 std::tuple<typename std::decay
00085 <decltype(g.get(selector<U>()))>::type
00086 ...>
00087 containers(g.get(selector<U>())...);
00088 return make_list(containers);
00089 }
00090 };
00091
00093 template <typename Generator>
00094 struct tuple_generator {
00095 private:
00096 Generator g;
00097
00098 public:
00099 tuple_generator(Generator&& g): g(std::move(g)) {}
00100 tuple_generator(const Generator& g): g(g) {}
00101
00102 tuple_generator(const tuple_generator& other): g(other.g) {}
00103 tuple_generator(tuple_generator&& other): g(std::move(other.g)) {}
00104
00105 template <typename U>
00106 decltype(tuple_generator_tool<U>()
00107 (std::declval<const Generator&>()))
00108 get(selector<U>) {
00109 return tuple_generator_tool<U>()(g);
00110 }
00111 };
00112 }
00113
00116 template <typename Generator>
00117 details::tuple_generator<typename std::decay<Generator>::type>
00118 tuple_gen(Generator&& g) {
00119 return details::tuple_generator<typename std::decay<Generator>::type>
00120 (std::forward<Generator>(g));
00121 }
00122 }
00123
00124 #endif