From 43f6b288c63fc929e693a31dd59991668bc65220 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 27 Jun 2016 15:07:57 +0200 Subject: [PATCH] Fix the non-constant array size problem Some compilers/libraries don't want to make my max() constexpr. --- include/xbt/functional.hpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/include/xbt/functional.hpp b/include/xbt/functional.hpp index 49d33f4e1c..9849224987 100644 --- a/include/xbt/functional.hpp +++ b/include/xbt/functional.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -100,17 +101,16 @@ template class Task; namespace bits { - // Something similar exist in C++14: - template - constexpr T max(T a, T b) - { - return (a > b) ? a : b; - } - template - constexpr T max(T a, Args... b) - { - return max(std::forward(a), max(std::forward(b)...)); - } + // Compute the maximum size taken by any of the given types: + template struct max_size; + template <> + struct max_size<> : public std::integral_constant {}; + template + struct max_size : public std::integral_constant {}; + template + struct max_size : public std::integral_constant max_size::value) ? sizeof(T) : max_size::value + > {}; struct whatever {}; @@ -126,11 +126,12 @@ namespace bits { void (whatever::* callback)(); whatever* data; }; - typedef char any_callback[max( - sizeof(ptr_callback), - sizeof(funcptr_callback), - sizeof(member_funcptr_callback) - )]; + constexpr std::size_t any_size = max_size< + ptr_callback, + funcptr_callback, + member_funcptr_callback + >::value; + typedef std::array any_callback; // Union of what we can store in a Task: union TaskErasure { @@ -218,14 +219,14 @@ public: } code; if (!std::is_empty::value) // AFAIU, this is safe as per [basic.types]: - std::memcpy(&code.code, &erasure.any, sizeof(code.code)); + std::memcpy(&code.code, erasure.any.data(), sizeof(code.code)); code.code(std::forward(args)...); }, // Destroy: nullptr }; if (!std::is_empty::value) - std::memcpy(&code_.any, &code, sizeof(code)); + std::memcpy(code_.any.data(), &code, sizeof(code)); vtable_ = &vtable; } -- 2.20.1