Created
March 2, 2021 23:42
-
-
Save CookiePLMonster/7f28097a33f96e228e4173ee4412f459 to your computer and use it in GitHub Desktop.
"Invalid template argument, expected compile-time constant expression" VS16.9.0 bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <array> | |
#include <cstddef> | |
#include <cstdint> | |
#include <type_traits> | |
namespace detail { | |
template<typename T, std::size_t rank, std::size_t... sizes> | |
struct DimensionalArrayExplicitRank; | |
// Workaround for VC2017 | |
#if defined(_MSC_VER) && _MSC_VER < 1920 | |
template<std::size_t rank, std::size_t... sizes> | |
struct GetRankSize | |
{ | |
static constexpr std::size_t size_array[] = {sizes...}; | |
static constexpr std::size_t value = size_array[rank - 1]; | |
}; | |
template<typename T, std::size_t rank, std::size_t... sizes> | |
using GetArrayImplType = | |
std::array<std::conditional_t<rank == 1, T, DimensionalArrayExplicitRank<T, rank - 1, sizes...>>, | |
GetRankSize<rank, sizes...>::value>; | |
#else | |
template<std::size_t rank, std::size_t... sizes> | |
constexpr std::size_t GetRankSize() | |
{ | |
constexpr std::size_t size_array[] = {sizes...}; | |
return size_array[rank - 1]; | |
} | |
template<typename T, std::size_t rank, std::size_t... sizes> | |
using GetArrayImplType = | |
std::array<std::conditional_t<rank == 1, T, DimensionalArrayExplicitRank<T, rank - 1, sizes...>>, | |
GetRankSize<rank, sizes...>()>; | |
#endif | |
template<typename T, std::size_t rank_param, std::size_t... sizes> | |
struct DimensionalArrayExplicitRank : public GetArrayImplType<T, rank_param, sizes...> | |
{ | |
static constexpr std::size_t rank = rank_param; | |
static_assert(rank > 0, "Attempted to create dimensional array with rank less than 1"); | |
using ArrayImplType = GetArrayImplType<T, rank, sizes...>; | |
using ArrayImplType::ArrayImplType; | |
template<typename Callable> | |
void enumerate(const Callable& f) | |
{ | |
for (auto& it : *this) | |
{ | |
if constexpr (rank == 1) | |
f(it); | |
else | |
it.enumerate(f); | |
} | |
} | |
template<typename Callable> | |
void enumerate(const Callable& f) const | |
{ | |
for (const auto& it : *this) | |
{ | |
if constexpr (rank == 1) | |
f(it); | |
else | |
it.enumerate(f); | |
} | |
} | |
}; | |
} // namespace detail | |
template<typename T, std::size_t... sizes> | |
using DimensionalArray = detail::DimensionalArrayExplicitRank<T, sizeof...(sizes), sizes...>; | |
static void enumerateDummy(void*& val) | |
{ | |
} | |
int main() | |
{ | |
DimensionalArray<void*, 2> batch_vertex_shaders{}; | |
DimensionalArray<void*, 2, 2, 9, 4> batch_fragment_shaders{}; | |
batch_vertex_shaders.enumerate(enumerateDummy); | |
batch_fragment_shaders.enumerate(enumerateDummy); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment