drivers/test_all_driver.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 __TEST_ALL_DRIVER_HH
00018 # define __TEST_ALL_DRIVER_HH
00019 
00020 # include "test_driver.hh"
00021 
00022 namespace catsfoot {
00023   namespace details {
00025     template <typename U>
00026     std::false_type has_get_axiom_helper(try_second, U&&) {
00027       static_assert(details::always_false<U>::value,
00028                     "Cannot use this function");
00029       return 0;
00030     }
00031 
00033     template <typename U,
00034               typename =
00035               decltype(U::get_axioms())>
00036     std::true_type has_get_axiom_helper(try_first, U&&) {
00037       static_assert(details::always_false<U>::value,
00038                     "Cannot use this function");
00039       return 0;
00040     }
00041 
00043     template <typename U>
00044     struct has_get_axiom:
00045       public identity
00046     <decltype(has_get_axiom_helper(try_first(),
00047                                    std::declval<U>()))>
00048     ::type {
00049     };
00050 
00052     template <typename T,
00053               bool = is_concept<T>::value,
00054               bool = has_get_axiom<T>::value>
00055     struct test_all {
00056       template <typename Generator,
00057                 typename Stream = decltype(std::cerr)>
00058       bool operator()(Generator&, Stream& = std::cerr) {
00059         return true;
00060       }
00061     };
00062 
00064     template <typename T>
00065     struct test_all<T, true, false> {
00066       template <typename Generator,
00067               typename Stream = decltype(std::cerr)>
00068       bool operator()(Generator& g, Stream& s = std::cerr) {
00069         return test_all<typename T::requirements>()(g, s);
00070       }
00071     };
00072 
00074     template <typename T>
00075     struct test_all<T, true, true> {
00076 
00078       template <typename Generator,
00079                 typename... Axioms,
00080                 typename Stream,
00081                 typename Index = std::integral_constant<size_t, 0> >
00082       bool test(Generator& g, const std::tuple<Axioms...>& axioms,
00083                 Stream& s, Index = Index()) {
00084         bool ret2 =
00085           ::catsfoot::test(g, std::get<1>(std::get<Index::value>(axioms)),
00086                            type_to_string<T>() + "::" +
00087                            std::get<0>(std::get<Index::value>(axioms)), s);
00088         bool ret =
00089           test(g, axioms, s, std::integral_constant<size_t, Index::value+1>());
00090         return ret && ret2;
00091       }
00092 
00094       template <typename Generator,
00095                 typename... Axioms,
00096                 typename Stream>
00097       bool test(Generator&, const std::tuple<Axioms...>&,
00098                 Stream&, std::integral_constant<size_t, sizeof...(Axioms)>) {
00099         return true;
00100       }
00101 
00102       template <typename Generator,
00103                 typename Stream = decltype(std::cerr)>
00104       bool operator()(Generator& g, Stream& s = std::cerr) {
00105         bool ret2 = test(g, T::get_axioms(), s);
00106         bool ret = test_all<typename T::requirements>()(g, s);
00107         return ret && ret2;
00108       }
00109     };
00110 
00112     template <typename T, typename... U, bool B>
00113     struct test_all<concept_list<T, U...>, false, B> {
00114       template <typename Generator,
00115                 typename Stream = decltype(std::cerr)>
00116       bool operator()(Generator& g, Stream& s = std::cerr) {
00117         bool ret = test_all<concept_list<U...> >()(g, s);
00118         bool ret2 = test_all<T>()(g, s);
00119         return ret && ret2;
00120       }
00121     };
00122   }
00123 
00125   template <typename Model,
00126             typename Generator,
00127             typename Stream = decltype(std::cerr)>
00128   bool test_all(Generator& g, Stream& s = std::cerr) {
00129     return details::test_all<Model>()(g, s);
00130   }
00131 
00132 }
00133 
00134 #endif
00135