From f0b86c4df13850fdc415a90768266271423f56b6 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 21 Aug 2017 16:28:50 +0200 Subject: [PATCH] Improve error message in hp::FECollection constructor --- doc/news/changes/minor/20170821DanielArndt | 5 +++++ include/deal.II/base/template_constraints.h | 22 +++++++++++++++++++++ include/deal.II/hp/fe_collection.h | 12 +++++++++++ 3 files changed, 39 insertions(+) create mode 100644 doc/news/changes/minor/20170821DanielArndt diff --git a/doc/news/changes/minor/20170821DanielArndt b/doc/news/changes/minor/20170821DanielArndt new file mode 100644 index 0000000000..13cfe6a365 --- /dev/null +++ b/doc/news/changes/minor/20170821DanielArndt @@ -0,0 +1,5 @@ +New: The struct is_base_of_all is a generalization of std::is_base_of +to template parameter packs and tests if all classes in the parameter pack +have a given class as base class or are this class. +
+(Daniel Arndt, 2017/08/21) diff --git a/include/deal.II/base/template_constraints.h b/include/deal.II/base/template_constraints.h index 0589d03bae..908d85e12d 100644 --- a/include/deal.II/base/template_constraints.h +++ b/include/deal.II/base/template_constraints.h @@ -25,6 +25,28 @@ DEAL_II_NAMESPACE_OPEN +namespace +{ + // helper struct for is_base_of_all + template struct BoolStorage; +} + +/** + * This struct is a generalization of std::is_base_of + * to template parameter packs and tests if all of the Derived... + * classes have Base as base class or are Base itself. The result + * is stored in the member variable value. + */ +template +struct is_base_of_all +{ + static constexpr bool value = + std::is_same::value..., true>, + BoolStorage::value...>>::value; +}; + + + template struct constraint_and_return_value; diff --git a/include/deal.II/hp/fe_collection.h b/include/deal.II/hp/fe_collection.h index f81839f2ab..6ed435e74d 100644 --- a/include/deal.II/hp/fe_collection.h +++ b/include/deal.II/hp/fe_collection.h @@ -454,6 +454,18 @@ namespace hp template FECollection::FECollection (const FETypes &... fes) { + static_assert(is_base_of_all, FETypes...>::value, + "Not all of the input parameters are derived from FiniteElement!"); + + // We want to call 'push_back' for each of the arguments. To do so parameter + // pack expansion comes in handy. Unfortunately, we can't just write + // push_back(fes)...; + // but have to treat this as arguments to some function which doesn't need + // to do anything with it. Now, + // [](...) {}(push_back(fes)...); + // doesn't work as well because the ellipsis cannot deal with no parameters + // at all. Hence, we extend the return value of each of the return values + // by zero using the comma operator. [](...) {}((push_back(fes),0)...); } -- 2.39.5