From ed71db1e8fc024a3c1b13268653f0a8812c56e34 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Mon, 17 Jun 2019 10:04:05 -0400 Subject: Use C++11-compatible assertions in constexpr functions C++11 restricts the bodies of constexpr functions more aggressively than C++14 or later. Introduce and use a C++11-compatible macro for assertions in constexpr functions. --- src/base/optional.h | 10 ++++------ src/base/utils.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/base/optional.h b/src/base/optional.h index 5ede4af..79300d5 100644 --- a/src/base/optional.h +++ b/src/base/optional.h @@ -16,6 +16,7 @@ #define ASTC_CODEC_BASE_OPTIONAL_H_ #include "src/base/type_traits.h" +#include "src/base/utils.h" #include #include @@ -350,8 +351,7 @@ class Optional return get(); } constexpr const T& value() const { - assert(this->constructed()); - return get(); + return ASTC_CONSTEXPR_ASSERT(this->constructed()), get(); } T* ptr() { return this->constructed() ? &get() : nullptr; } @@ -372,8 +372,7 @@ class Optional return get(); } constexpr const T& operator*() const { - assert(this->constructed()); - return get(); + return ASTC_CONSTEXPR_ASSERT(this->constructed()), get(); } T* operator->() { @@ -381,8 +380,7 @@ class Optional return &get(); } constexpr const T* operator->() const { - assert(this->constructed()); - return &get(); + return ASTC_CONSTEXPR_ASSERT(this->constructed()), &get(); } ~Optional() { diff --git a/src/base/utils.h b/src/base/utils.h index 0a4fabd..610066b 100644 --- a/src/base/utils.h +++ b/src/base/utils.h @@ -32,4 +32,21 @@ #define UTILS_RELEASE_ASSERT(x) assert(x) #endif +// In C++11, `assert` can't be used portably within constexpr functions. +// ASTC_CONSTEXPR_ASSERT functions as a runtime assert but works in C++11 +// constexpr functions. Example: +// +// constexpr double Divide(double a, double b) { +// return ASTC_CONSTEXPR_ASSERT(b != 0), a / b; +// } +// +// This macro is based on ABSL_ASSERT. +#ifdef NDEBUG +#define ASTC_CONSTEXPR_ASSERT(expr) \ + (false ? static_cast(expr) : static_cast(0)) +#else +#define ASTC_CONSTEXPR_ASSERT(expr) \ + ((expr) ? static_cast(0) : [] { assert(false && #expr); }()) +#endif + #endif // ASTC_CODEC_BASE_UTILS_H_ -- cgit v1.2.3