diff --git a/spot/kripke/kripke.hh b/spot/kripke/kripke.hh index 519d9981c..bb71efe8c 100644 --- a/spot/kripke/kripke.hh +++ b/spot/kripke/kripke.hh @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2009, 2010, 2013, 2014, 2016, 2017 Laboratoire de Recherche -// et Developpement de l'Epita +// Copyright (C) 2009, 2010, 2013, 2014, 2016, 2017, 2019 Laboratoire +// de Recherche et Developpement de l'Epita // // This file is part of Spot, a model checking library. // @@ -22,9 +22,11 @@ #include #include #include +#include namespace spot { + /// \ingroup kripke /// \brief This class is a template representation of a Kripke /// structure. It is composed of two template parameters: State /// represents a state of the Kripke structure, SuccIterator is @@ -42,6 +44,9 @@ namespace spot /// is used internally for sharing this structure among threads. State initial(unsigned tid); + /// \brief Returns the number of threads that are handled by the kripkecube + unsigned get_threads(); + /// \brief Provides a string representation of the parameter state std::string to_string(const State, unsigned tid) const; @@ -56,40 +61,56 @@ namespace spot const std::vector get_ap(); }; - /// \brief This method allows to ensure (at compile time) if +#ifndef SWIG + + /// \ingroup kripke + /// \brief This class allows to ensure (at compile time) if /// a given parameter is of type kripkecube. It also check /// if the iterator has the good interface. - template - bool is_a_kripkecube(kripkecube&) + template + class is_a_kripkecube_ptr { - // Hardly waiting C++17 concepts... - State (kripkecube::*test_initial)(unsigned) = - &kripkecube::initial; - std::string (kripkecube::*test_to_string) - (const State, unsigned) const = &kripkecube::to_string; - void (kripkecube::*test_recycle)(SuccIter*, unsigned) = - &kripkecube::recycle; - const std::vector - (kripkecube::*test_get_ap)() = - &kripkecube::get_ap; - void (SuccIter::*test_next)() = &SuccIter::next; - State (SuccIter::*test_state)() const= &SuccIter::state; - bool (SuccIter::*test_done)() const= &SuccIter::done; - cube (SuccIter::*test_condition)() const = &SuccIter::condition; + private: + using yes = std::true_type; + using no = std::false_type; - // suppress warnings about unused variables - (void) test_initial; - (void) test_to_string; - (void) test_recycle; - (void) test_get_ap; - (void) test_next; - (void) test_state; - (void) test_done; - (void) test_condition; + // Hardly waiting C++ concepts... + template static auto test_kripke(U u, V v) + -> decltype( + // Check the kripke + std::is_sameinitial(0))>::value && + std::is_sameget_threads())>::value && + std::is_sameto_string(State(), 0))>::value && + std::is_samesucc(State(), 0))>::value && + std::is_samerecycle(nullptr, 0))>::value && + std::is_same, + decltype(u->get_ap())>::value && + std::is_samerecycle(nullptr, 0))>::value && + + // Check the SuccIterator + std::is_samenext())>::value && + std::is_samedone())>::value && + std::is_samestate())>::value && + std::is_samecondition())>::value + + // finally return the type "yes" + , yes() + ); + + // For all other cases return the type "no" + template static no test_kripke(...); + + public: + + /// \brief Checking this value will ensure, at compile time, that the + /// Kripke specialisation respects the required interface. + static constexpr bool value = + std::is_same< decltype(test_kripke(nullptr, nullptr)), yes + >::value; + }; + +#endif - // Always return true since otherwise a compile-time error will be raised. - return true; - } /// \ingroup kripke /// \brief Iterator code for Kripke structure diff --git a/spot/ltsmin/spins_kripke.hh b/spot/ltsmin/spins_kripke.hh index 7e9eac374..1e20d3b13 100644 --- a/spot/ltsmin/spins_kripke.hh +++ b/spot/ltsmin/spins_kripke.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2017, 2018 Laboratoire de Recherche et Développement de +// Copyright (C) 2017, 2018, 2019 Laboratoire de Recherche et Développement de // l'Epita (LRDE) // // This file is part of Spot, a model checking library. diff --git a/spot/mc/bloemen.hh b/spot/mc/bloemen.hh index 6dacae74c..f2c9fa9d7 100644 --- a/spot/mc/bloemen.hh +++ b/spot/mc/bloemen.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2015, 2016, 2017, 2018 Laboratoire de Recherche et +// Copyright (C) 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et // Developpement de l'Epita // // This file is part of Spot, a model checking library. @@ -432,7 +432,9 @@ namespace spot sys_(sys), uf_(uf), tid_(tid), nb_th_(std::thread::hardware_concurrency()) { - SPOT_ASSERT(is_a_kripkecube(sys)); + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); } using uf = iterable_uf; diff --git a/spot/mc/bloemen_ec.hh b/spot/mc/bloemen_ec.hh index f3412e4dc..d80f9cd89 100644 --- a/spot/mc/bloemen_ec.hh +++ b/spot/mc/bloemen_ec.hh @@ -475,7 +475,9 @@ namespace spot nb_th_(std::thread::hardware_concurrency()), stop_(stop) { - SPOT_ASSERT(is_a_kripkecube(sys)); + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); } using uf = iterable_uf_ec; diff --git a/spot/mc/cndfs.hh b/spot/mc/cndfs.hh index 14d5271bd..d84daf88a 100644 --- a/spot/mc/cndfs.hh +++ b/spot/mc/cndfs.hh @@ -117,7 +117,9 @@ namespace spot sizeof(local_colors)*(std::thread::hardware_concurrency() - 1)), stop_(stop) { - SPOT_ASSERT(is_a_kripkecube(sys)); + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); } virtual ~swarmed_cndfs() diff --git a/spot/mc/deadlock.hh b/spot/mc/deadlock.hh index da94c7b66..ebd465040 100644 --- a/spot/mc/deadlock.hh +++ b/spot/mc/deadlock.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2015, 2016, 2017, 2018 Laboratoire de Recherche et +// Copyright (C) 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et // Developpement de l'Epita // // This file is part of Spot, a model checking library. @@ -103,7 +103,9 @@ namespace spot p_pair_(sizeof(deadlock_pair)), stop_(stop) { - SPOT_ASSERT(is_a_kripkecube(sys)); + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); } virtual ~swarmed_deadlock() diff --git a/spot/mc/intersect.hh b/spot/mc/intersect.hh index eadb4a9a2..9b619329b 100644 --- a/spot/mc/intersect.hh +++ b/spot/mc/intersect.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2015, 2016, 2018 Laboratoire de Recherche et +// Copyright (C) 2015, 2016, 2018, 2019 Laboratoire de Recherche et // Developpement de l'Epita // // This file is part of Spot, a model checking library. @@ -66,7 +66,9 @@ namespace spot twacube_ptr twa, unsigned tid, bool& stop): sys_(sys), twa_(twa), tid_(tid), stop_(stop) { - SPOT_ASSERT(is_a_kripkecube(sys)); + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); map.reserve(2000000); todo.reserve(100000); } diff --git a/spot/mc/reachability.hh b/spot/mc/reachability.hh index 5ea406bc1..53d82e728 100644 --- a/spot/mc/reachability.hh +++ b/spot/mc/reachability.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2015, 2016 Laboratoire de Recherche et +// Copyright (C) 2015, 2016, 2019 Laboratoire de Recherche et // Developpement de l'Epita // // This file is part of Spot, a model checking library. @@ -34,8 +34,10 @@ namespace spot public: seq_reach_kripke(kripkecube& sys, unsigned tid): sys_(sys), tid_(tid) - { - SPOT_ASSERT(is_a_kripkecube(sys)); + { + static_assert(spot::is_a_kripkecube_ptr::value, + "error: does not match the kripkecube requirements"); visited.reserve(2000000); todo.reserve(100000); } diff --git a/tests/ltsmin/modelcheck.cc b/tests/ltsmin/modelcheck.cc index 018aa4472..dce2a6285 100644 --- a/tests/ltsmin/modelcheck.cc +++ b/tests/ltsmin/modelcheck.cc @@ -215,7 +215,6 @@ static std::string split_filename(const std::string& str) { return str.substr(found+1); } - static int checked_main() { spot::default_environment& env =