4#ifndef MEASUREMENTCONTAINERWITHDIMENSION_H
5#define MEASUREMENTCONTAINERWITHDIMENSION_H
12template <
typename container_t, std::
size_t DIM>
29#ifdef ENABLE_DEBUG_TRACE
30#define DEBUG_TRACE(a) do { a; } while (0)
32#define DEBUG_TRACE(a) do { } while (0)
40template <
typename derived_t,
typename ...T_Container>
47 const derived_t &
derived()
const {
return *
static_cast<const derived_t *
>(
this); }
52 template <std::
size_t N=std::variant_size_v< measurement_container_variant_t > >
53 static constexpr std::size_t
dimMax(std::size_t max_dim=0ul) {
56 return dimMax<N-1>(std::max( this_variant_type::dimension(), max_dim ) );
61 template <
typename container_t, std::
size_t N>
64 return std::is_same<container_t, typename this_variant_type::container_type>::value;
68 template <
typename container_t, std::
size_t N= std::variant_size_v< measurement_container_variant_t > >
77 template <
typename container_t, std::
size_t N= std::variant_size_v< measurement_container_variant_t > >
88 using this_container_type =
typename this_variant_type::container_type;
89 if constexpr(std::is_base_of_v<container_t, this_container_type>
90 && std::has_virtual_destructor_v<this_container_type> && std::has_virtual_destructor_v<container_t>) {
91 return countDerivedVariants<container_t, N-1>(
a)+ (
dynamic_cast<const this_container_type *
>(&
a) !=
nullptr );
100 template <std::
size_t N= std::variant_size_v< measurement_container_variant_t > >
104 out << N-1 <<
": " <<
typeid(a_type).name() << std::endl;
110 std::stringstream
msg;
111 msg <<
"Container " <<
a <<
" not in variant:" << std::endl;
113 throw std::runtime_error(
msg.str());
116 template <
typename container_t,
bool check_dimension, std::
size_t N >
123 return this_variant_type();
127 using this_container_type =
typename this_variant_type::container_type ;
128 DEBUG_TRACE( std::cout <<
"DEBUG search option for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
129 <<
" option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
130 <<
" check dimension ? " << check_dimension <<
" desired dimension " << dimension
132 if constexpr(std::is_same_v<this_container_type, container_t>) {
140 DEBUG_TRACE( std::cout <<
"DEBUG --> for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
141 <<
" foumd unambiguous option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
148 if (this_variant_type::dimension() == dimension) {
149 DEBUG_TRACE( std::cout <<
"DEBUG --> for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
150 <<
" foumd dimension option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
156 else if constexpr(std::is_base_of_v<container_t, this_container_type>) {
158 if constexpr(std::has_virtual_destructor_v<this_container_type> && std::has_virtual_destructor_v<container_t>) {
161 const this_container_type *derived_container =
dynamic_cast<const this_container_type *
>(&
a);
162 if (derived_container) {
165 if constexpr(!check_dimension) {
173 DEBUG_TRACE( std::cout <<
"DEBUG --> for " <<
typeid(this_container_type).name() <<
" (aka " <<
typeid(
a).name() <<
")"
174 <<
" foumd derived option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
180 if (this_variant_type::dimension() == dimension) {
181 DEBUG_TRACE( std::cout <<
"DEBUG --> for " <<
typeid(this_container_type).name() <<
" (aka " <<
typeid(
a).name() <<
")"
182 <<
" derived with dimension option: " << N <<
" " <<
typeid(this_container_type).name()
183 <<
" dim " << this_variant_type::dimension()
195 template <
typename container_t, std::
size_t N>
203 using this_container_type =
typename this_variant_type::container_type;
205 DEBUG_TRACE( std::cout <<
"DEBUG determin dimension for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
206 <<
" option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
209 if constexpr(std::is_same<container_t, this_container_type>::value) {
210 DEBUG_TRACE( std::cout <<
"DEBUG get dimension for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
211 <<
" option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
213 return derived_t::getDimension(
a);
215 else if constexpr(std::is_base_of_v<container_t, this_container_type>) {
216 DEBUG_TRACE( std::cout <<
"DEBUG try get dimension for derived " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
217 <<
" option: " << N <<
" " <<
typeid(this_container_type).name() <<
" dim " << this_variant_type::dimension()
220 if constexpr(std::has_virtual_destructor_v<this_container_type> && std::has_virtual_destructor_v<container_t>) {
227 const this_container_type *derived_container =
dynamic_cast<const this_container_type *
>(&
a);
228 if (derived_container) {
229 return derived_t::getDimension(*derived_container);
238 template <
typename container_t, std::
size_t = std::variant_size_v< measurement_container_variant_t > >
242 static constexpr std::size_t NVariants = std::variant_size_v< measurement_container_variant_t >;
243 if constexpr( variant_multiplicity == 1) {
247 if (variant_multiplicity==0) {
252 DEBUG_TRACE( std::cout <<
"DEBUG need to search with dimension check for " <<
typeid(container_t).name() <<
" (aka " <<
typeid(
a).name() <<
")"
260template <
typename derived_t,
typename... T_Container>
285 template <
typename container_t>
292 && std::get<0>(
m_containerList[container_index]).containerPtr() ==
nullptr) {
294 std::runtime_error(
"Unhandled measurement type");
Base::measurement_container_variant_t measurement_container_variant_t
const measurement_container_variant_t & at(std::size_t container_index) const
static constexpr std::size_t getMeasurementDimMax()
void setContainer(std::size_t container_index, const container_t &container)
const std::vector< measurement_container_variant_t > & containerList() const
std::vector< measurement_container_variant_t > m_containerList
static void dumpVariantTypes()
MeasurementContainerWithDimension< derived_t, T_Container... > Base
static void throwContainerNotInVariant(const char *a)
const derived_t & derived() const
static unsigned int countDerivedVariants(const container_t &a)
static unsigned int getDimensionOfDerivedVariantOption(const container_t &a)
static constexpr unsigned int countVariants()
static void dumpVariantTypes(std::ostream &out)
static measurement_container_variant_t getContainerWithDimensionNoAmbiguities(const container_t &a, unsigned int dimension=0)
static constexpr bool isSameContainer()
std::variant< T_Container... > measurement_container_variant_t
static measurement_container_variant_t getContainerWithDimension(const container_t &a)
static constexpr T lvalue(T &&a)
static constexpr std::size_t dimMax(std::size_t max_dim=0ul)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
ContainerRefWithDim(const container_t &container)
container_t container_type
const container_t & container() const
const container_t * containerPtr() const
const container_t * m_container
static constexpr std::size_t s_dimension
static constexpr std::size_t dimension()