From dc2d367d062ea093e036172e003ad90d4cb030ee Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth <bangerth@colostate.edu> Date: Thu, 14 Sep 2017 14:41:08 -0600 Subject: [PATCH] Allow not specifying the multiplicity in the FESystem constructor. --- include/deal.II/fe/fe_system.h | 51 ++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/include/deal.II/fe/fe_system.h b/include/deal.II/fe/fe_system.h index caa7920589..f9218330df 100644 --- a/include/deal.II/fe/fe_system.h +++ b/include/deal.II/fe/fe_system.h @@ -448,12 +448,30 @@ public: * elements. The temporary is destroyed again at the end of the code that * corresponds to this line, but this does not matter because FESystem * creates its own copy of the FE_Q object. + * + * As a shortcut, this constructor also allows calling + * @code + * FESystem<dim> fe (FE_Q<dim>(2)^dim, FE_Q<dim>(1)); + * @endcode + * instead of the more explicit + * @code + * FESystem<dim> fe (FE_Q<dim>(2)^dim, FE_Q<dim>(1)^1); + * @endcode + * In other words, if no multiplicity for an element is explicitly specified + * via the exponentiation operation, then it is assumed to be one (as one + * would have expected). */ template <class... FEPairs, - typename = typename std::enable_if<all_same_as<typename std::decay<FEPairs>::type..., - std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, - unsigned int>>::value>::type> - FESystem (FEPairs&& ... fe_pairs); + typename = typename enable_if_all< + (std::is_same<typename std::decay<FEPairs>::type, + std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>::value + || + std::is_base_of<FiniteElement<dim, spacedim>, + typename std::decay<FEPairs>::type>::value) + ... + >::type + > + FESystem (FEPairs &&... fe_pairs); /** * Same as above allowing the following syntax: @@ -1149,6 +1167,26 @@ namespace return fe_system.second > 0; }); } + + + + template <int dim, int spacedim> + std::pair<std::unique_ptr<FiniteElement<dim, spacedim> >, unsigned int> + promote_to_fe_pair (const FiniteElement<dim,spacedim> &fe) + { + return std::make_pair<std::unique_ptr<FiniteElement<dim, spacedim> >, + unsigned int> (std::move(fe.clone()), 1u); + } + + + + template <int dim, int spacedim> + auto + promote_to_fe_pair (std::pair<std::unique_ptr<FiniteElement<dim, spacedim> >, unsigned int> &&p) + -> decltype(std::forward<std::pair<std::unique_ptr<FiniteElement<dim, spacedim> >, unsigned int> >(p)) + { + return std::forward<std::pair<std::unique_ptr<FiniteElement<dim, spacedim> >, unsigned int> >(p); + } } @@ -1157,10 +1195,11 @@ namespace // If we decide to remove the deprecated constructors, we might just use the variadic // constructor with a suitable static_assert instead of the std::enable_if. template<int dim, int spacedim> -template <class... FEPairs, typename> +template <class... FEPairs, + typename> FESystem<dim,spacedim>::FESystem (FEPairs &&... fe_pairs) : - FESystem<dim, spacedim> ({std::forward<FEPairs>(fe_pairs)...}) + FESystem<dim, spacedim> ({promote_to_fe_pair<dim,spacedim>(std::forward<FEPairs>(fe_pairs))...}) {} -- 2.39.5