dataset/choose.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 __CHOOSE_HH
00018 # define __CHOOSE_HH
00019 
00020 namespace catsfoot {
00021   namespace details {
00022     template <typename...>
00023     struct generator_choose {};
00024 
00025     template <typename T, typename... Other>
00026     struct generator_choose<T, Other...>
00027       : public generator_choose<Other...> {
00028     private:
00029       typedef generator_choose<Other...> super;
00030       T generator;
00031 
00032     public:
00033       generator_choose(T t, Other... other)
00034         : generator_choose<Other...>(std::forward<Other>(other)...),
00035           generator(std::forward<T>(t)) {
00036       }
00037 
00038       template <typename Return,
00039                 ENABLE_IF(generator_for<T, Return>),
00040                 typename Ret = typename
00041               is_callable<member_get(T&, selector<Return>)>::result_type>
00042       Ret get(selector<Return> s) {
00043         return generator.get(s);
00044       }
00045 
00046       template <typename Return,
00047                 ENABLE_IF_NOT(generator_for<T, Return>),
00048                 ENABLE_IF(generator_for<super, Return>),
00049                 typename Ret = typename
00050                 is_callable<member_get(super&,
00051                                        selector<Return>)>::result_type>
00052       Ret get(selector<Return> s...) {
00053         return this->super::get(s);
00054       }
00055     };
00056   }
00057 
00063   template <typename... T>
00064   details::generator_choose<typename std::decay<T>::type...>
00065   choose(T&&... t) {
00066     return details::generator_choose<typename std::decay<T>::type...>
00067       {std::forward<T>(t)...};
00068   }
00069 
00070 }
00071 
00072 #endif