aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@google.com>2019-06-17 10:04:05 -0400
committerGravatar Benjamin Barenblat <bbaren@google.com>2019-06-17 10:04:05 -0400
commited71db1e8fc024a3c1b13268653f0a8812c56e34 (patch)
tree021ecff0d3f08162bf202d2c32860cb394bfb7a5
parent6eed60043b7b93407982d9fd3f1822aaf46afc17 (diff)
Use C++11-compatible assertions in constexpr functionsHEADmaster
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.
-rw-r--r--src/base/optional.h10
-rw-r--r--src/base/utils.h17
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 <cassert>
#include <initializer_list>
@@ -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<void>(expr) : static_cast<void>(0))
+#else
+#define ASTC_CONSTEXPR_ASSERT(expr) \
+ ((expr) ? static_cast<void>(0) : [] { assert(false && #expr); }())
+#endif
+
#endif // ASTC_CODEC_BASE_UTILS_H_