vtk-m/vtkm/internal/VariantDetail.h.in
Kenneth Moreland d80a8125cc Sprinkle noexcept goodness on Variant and ArrayPortalMultiplexer
Allow Variant copy constructor/operators and its CastAndCall to operate
in noexcept methods. This can help the compiler make optimizations.
2019-07-25 15:25:29 -06:00

211 lines
6.0 KiB
C

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
$# This file uses the pyexpander macro processing utility to build the
$# FunctionInterface facilities that use a variable number of arguments.
$# Information, documentation, and downloads for pyexpander can be found at:
$#
$# http://pyexpander.sourceforge.net/
$#
$# To build the source code, execute the following (after installing
$# pyexpander, of course):
$#
$# expander.py VariantDetail.h.in > VariantDetail.h
$#
$# Ignore the following comment. It is meant for the generated file.
// **** DO NOT EDIT THIS FILE!!! ****
// This file is automatically generated by VariantDetail.h.in
#ifndef vtk_m_internal_VariantDetail_h
#define vtk_m_internal_VariantDetail_h
#ifndef vtk_m_internal_Variant_h
#error VariantDetail.h must be included from Variant.h
#endif
#include <vtkm/Types.h>
#include <vtkm/internal/brigand.hpp>
#include <type_traits>
$py(max_expanded=20)\
$# Python commands used in template expansion.
$py(
def type_list(num_params):
if num_params < 0:
return ''
result = 'T0'
for param in range(1, num_params + 1):
result += ', T%d' % param
return result
)\
$#
$extend(type_list)\
namespace vtkm
{
namespace internal
{
namespace detail
{
template <typename ReturnType>
struct VariantDummyReturn
{
VTKM_EXEC_CONT static inline ReturnType F() noexcept { return ReturnType{}; }
};
template <>
struct VariantDummyReturn<void>
{
VTKM_EXEC_CONT static inline void F() noexcept {}
};
template <typename ReturnType, typename Functor, typename... Args>
VTKM_EXEC_CONT inline ReturnType VariantCastAndCallImpl(brigand::list<>,
vtkm::IdComponent,
Functor&&,
const void*,
Args&&...) noexcept
{
// If we are here, it means we failed to find the appropriate type in a variant
VTKM_ASSERT(false && "Internal error, bad Variant state.");
return VariantDummyReturn<ReturnType>::F();
}
// clang-format off
$for(num_params in range(0, max_expanded))\
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename ReturnType,
$for(param_index in range(0, num_params + 1))\
typename T$(param_index),
$endfor\
typename Functor,
typename... Args>
VTKM_EXEC_CONT inline ReturnType VariantCastAndCallImpl(
brigand::list<$type_list(num_params)>,
vtkm::IdComponent index,
Functor&& f,
const void* storage,
Args&&... args) noexcept(noexcept(f(std::declval<const T0&>(), args...)))
{
switch (index)
{
$for(param_index in range(0, num_params + 1))\
case $(param_index):
return f(*reinterpret_cast<const T$(param_index)*>(storage), std::forward<Args>(args)...);
$endfor\
default:
// If we are here, it means we failed to find the appropriate type in a variant
VTKM_ASSERT(false && "Internal error, bad Variant state.");
return VariantDummyReturn<ReturnType>::F();
}
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename ReturnType,
$for(param_index in range(0, num_params + 1))\
typename T$(param_index),
$endfor\
typename Functor,
typename... Args>
VTKM_EXEC_CONT inline ReturnType VariantCastAndCallImpl(
brigand::list<$type_list(num_params)>,
vtkm::IdComponent index,
Functor&& f,
void* storage,
Args&&... args) noexcept(noexcept(f(std::declval<const T0&>(), args...)))
{
switch (index)
{
$for(param_index in range(0, num_params + 1))\
case $(param_index):
return f(*reinterpret_cast<T$(param_index)*>(storage), std::forward<Args>(args)...);
$endfor\
default:
// If we are here, it means we failed to find the appropriate type in a variant
VTKM_ASSERT(false && "Internal error, bad Variant state.");
return VariantDummyReturn<ReturnType>::F();
}
}
$endfor\
//clang-format on
// Recurse for cases where Variant has more than $(max_expanded) types
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename ReturnType,
$for(param_index in range(0, max_expanded + 1))\
typename T$(param_index),
$endfor\
typename... RemainingT,
typename Functor,
typename... Args>
VTKM_EXEC_CONT inline ReturnType VariantCastAndCallImpl(
brigand::list<$type_list(max_expanded), RemainingT...>,
vtkm::IdComponent index,
Functor&& f,
const void* storage,
Args&&... args) noexcept(noexcept(f(std::declval<const T0&>(), args...)))
{
if (index < $(max_expanded))
{
return VariantCastAndCallImpl<ReturnType>(
brigand::list<$type_list(max_expanded - 1)>{},
index,
f,
storage,
args...);
}
else
{
return VariantCastAndCallImpl<ReturnType>(
brigand::list<T$(max_expanded), RemainingT...>{}, index - $(max_expanded), f, storage, args...);
}
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename ReturnType,
$for(param_index in range(0, max_expanded + 1))\
typename T$(param_index),
$endfor\
typename... RemainingT,
typename Functor,
typename... Args>
VTKM_EXEC_CONT inline ReturnType VariantCastAndCallImpl(
brigand::list<$type_list(max_expanded), RemainingT...>,
vtkm::IdComponent index,
Functor&& f,
void* storage,
Args&&... args) noexcept(noexcept(f(std::declval<const T0&>(), args...)))
{
if (index < $(max_expanded))
{
return VariantCastAndCallImpl<ReturnType>(
brigand::list<$type_list(max_expanded - 1)>{},
index,
f,
storage,
args...);
}
else
{
return VariantCastAndCallImpl<ReturnType>(
brigand::list<T$(max_expanded), RemainingT...>{}, index - $(max_expanded), f, storage, args...);
}
}
}
}
} // vtkm::internal::detail
#endif //vtk_m_internal_VariantDetail_h