Program Listing for File competence_pack_union.hxx
↰ Return to documentation for file (mesh_handle/internal/competence_pack_union.hxx)
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element classes in parallel.
Copyright (C) 2026 the developers
t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#include <type_traits>
namespace t8_mesh_handle
{
template <template <typename> class... TCompetence>
struct element_competence_pack;
template <template <typename> class... TCompetence>
struct mesh_competence_pack;
namespace detail
{
// --- Unique insertion of one competence into a competence pack. ---
template <template <class> class TType>
struct tag
{
};
template <template <class> class TCompetence, template <class> class... TUnionCompetences>
inline constexpr bool contains_tag_v = std::disjunction_v<std::is_same<tag<TCompetence>, tag<TUnionCompetences>>...>;
template <template <template <typename> class...> class TPackType, template <class> class TCompetence,
template <class> class... TUnionCompetences>
using insert_unique = std::conditional_t<contains_tag_v<TCompetence, TUnionCompetences...>,
TPackType<TUnionCompetences...>, TPackType<TUnionCompetences..., TCompetence>>;
//--- Unique fold operation to fold competences into one competence pack without duplication. ---
template <template <template <typename> class...> class TPackType, typename TCompetencePack,
template <class> class... TCompetences>
struct fold_unique;
template <template <template <typename> class...> class TPackType, template <class> class... TUnionCompetences>
struct fold_unique<TPackType, TPackType<TUnionCompetences...>>
{
using type = TPackType<TUnionCompetences...>;
};
template <template <template <typename> class...> class TPackType, template <class> class... TUnionCompetences,
template <class> class TCompetence, template <class> class... TOtherCompetences>
struct fold_unique<TPackType, TPackType<TUnionCompetences...>, TCompetence, TOtherCompetences...>
{
using type = typename fold_unique<TPackType, insert_unique<TPackType, TCompetence, TUnionCompetences...>,
TOtherCompetences...>::type;
};
//--- Unique union of two competence packs. ---
template <typename TPack1, typename TPack2>
struct union_two_competence_packs;
template <template <class> class... TCompetences1, template <class> class... TCompetences2>
struct union_two_competence_packs<element_competence_pack<TCompetences1...>, element_competence_pack<TCompetences2...>>
{
using type =
typename fold_unique<element_competence_pack, element_competence_pack<TCompetences1...>, TCompetences2...>::type;
};
template <template <class> class... TCompetences1, template <class> class... TCompetences2>
struct union_two_competence_packs<mesh_competence_pack<TCompetences1...>, mesh_competence_pack<TCompetences2...>>
{
using type =
typename fold_unique<mesh_competence_pack, mesh_competence_pack<TCompetences1...>, TCompetences2...>::type;
};
//--- Recursive union of multiple competence packs using the implementation for two packs. ---
template <typename TPack, typename... TPacks>
struct union_competence_packs
{
using type = typename union_two_competence_packs<TPack, typename union_competence_packs<TPacks...>::type>::type;
};
template <typename TPack>
struct union_competence_packs<TPack>
{
using type = TPack;
};
} // namespace detail
} // namespace t8_mesh_handle