d80a8125cc
Allow Variant copy constructor/operators and its CastAndCall to operate in noexcept methods. This can help the compiler make optimizations.
211 lines
6.0 KiB
C
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
|