dataset/dataset.hh

00001 // This file is a part of Catsfoot.
00002 // Copyright (C) 2011  Uni Research
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #ifndef __DATASET_HH
00018 # define __DATASET_HH
00019 
00020 # include "../concept/concept_tools.hh"
00021 # include <list>
00022 # include "position.hh"
00023 # include "../type_traits/identity.hh"
00024 # include <initializer_list>
00025 # include "../wrappers/members.hh"
00026 # include "../type_traits/is_callable.hh"
00027 # include "../type_traits/always_false.hh"
00028 
00029 namespace catsfoot {
00030   DEF_MEMBER_WRAPPER(begin);
00031   DEF_MEMBER_WRAPPER(end);
00032   DEF_MEMBER_WRAPPER(get);
00033 
00035   template <typename T>
00036   struct selector {
00037     typedef T type;
00038   };
00039 
00042   template <typename T, typename ValueType>
00043   struct container: public auto_concept {
00044     typedef concept_list<
00045       is_callable<member_begin(T)>,
00046       is_callable<member_end(T)>
00047       > requirements;
00048   };
00049 
00052   template <typename T, typename Type>
00053   struct generator_for: public auto_concept {
00054     typedef concept_list<
00055       is_callable<member_get(T, selector<Type>)>,
00056       container<typename is_callable<member_get(T, selector<Type>)>
00057                 ::result_type,
00058                 Type>
00059       > requirements;
00060   };
00061 
00064   struct default_generator {
00065     template <typename Return,
00066               typename NonRefReturn = typename std::decay<Return>::type>
00067     std::list<NonRefReturn> get(selector<Return>) const {
00068       return std::list<NonRefReturn>{NonRefReturn()};
00069     }
00070   };
00071 
00074   template <typename... T>
00075   struct list_data_generator {
00076   private:
00077     std::tuple<std::list<T>...> containers;
00078 
00079   public:
00080     list_data_generator(std::initializer_list<T>... lists):
00081       containers(lists...) {}
00082 
00083     list_data_generator(const list_data_generator&) = default;
00084 
00085     template <typename Return,
00086               typename NonRefReturn = typename std::decay<Return>::type,
00087               typename pos
00088               = typename details::position<NonRefReturn, T...>::type
00089               >
00090     std::list<NonRefReturn>& get(selector<Return>) {
00091       return std::get<pos::value>
00092         (containers);
00093     }
00094 
00095     template <typename Return,
00096               typename NonRefReturn = typename std::decay<Return>::type,
00097               typename pos
00098               = typename details::position<NonRefReturn, T...>::type>
00099     const std::list<NonRefReturn>& get(selector<Return>) const {
00100       return std::get<pos::value>
00101         (containers);
00102     }
00103   };
00104 }
00105 
00106 #endif