VRM_CORE_ALWAYS_INLINE constexpr static void exec( TF&& f, Ts&&... xs) noexcept(noexcept(IMPL_FORNARGS_BODY())) { VRM_CORE_STATIC_ASSERT( TArity > 0, "Unallowed arity: must be greater than 0"); VRM_CORE_STATIC_ASSERT(sizeof...(Ts) % TArity == 0, "Unallowed arity: not divisible by number of arguments"); IMPL_FORNARGS_BODY(); }
VRM_CORE_ALWAYS_INLINE constexpr auto to_num(const TIn& x) noexcept { VRM_CORE_STATIC_ASSERT( // . std::is_arithmetic<underlying_if_strong_typedef_type<TOut>>{}, "`TOut` output type must be an arithmetic type."); VRM_CORE_STATIC_ASSERT( // . std::is_arithmetic<underlying_if_strong_typedef_type<TIn>>{}, "`TIn` input type must be an arithmetic type."); VRM_CORE_CONSTEXPR_ASSERT((!impl::will_overflow<TOut, TIn>(x))); return static_cast<TOut>(x); }
VRM_CORE_ALWAYS_INLINE constexpr decltype(auto) storage_cast( TStorage * storage) noexcept { VRM_CORE_STATIC_ASSERT( // . sizeof(typename TStorage::type) >= sizeof(T), // . "`TStorage` is not big enough for `T`."); VRM_CORE_STATIC_ASSERT( // . alignof(typename TStorage::type) >= alignof(T), // . "`TStorage` is not properly aligned for `T`."); VRM_CORE_ASSERT_OP(storage, !=, nullptr); using return_type = copy_cv_qualifiers<T, TStorage>; return reinterpret_cast<return_type*>(storage); }