1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TYPES_ALWAYS_FALSE_H_ 6 #define BASE_TYPES_ALWAYS_FALSE_H_ 7 8 namespace base { 9 10 // A helper that can be used with a static_assert() that must always fail (e.g. 11 // for an undesirable template instantiation). Such a static_assert() cannot 12 // simply be written as static_assert(false, ...) because that would always fail 13 // to compile, even if the template was never instantiated. Instead, a common 14 // idiom is to force the static_assert() to depend on a template parameter so 15 // that it is only evaluated when the template is instantiated: 16 // 17 // template <typename U = T> 18 // void SomeDangerousMethodThatShouldNeverCompile() { 19 // static_assert(base::AlwaysFalse<U>, "explanatory message here"); 20 // } 21 // 22 // 23 // The issue of not being able to use static_assert(false, ...) in a 24 // non-instantiated template was fixed in C++23. When Chromium switches to 25 // building with C++23, remove this file and use false directly, and search 26 // across the Chromium codebase for "AlwaysFalse", as there are other 27 // implementations in places that cannot depend on this file. 28 // 29 // References: 30 // - https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2593r0.html 31 // - https://github.com/cplusplus/papers/issues/1251 32 33 namespace internal { 34 35 template <typename... Args> 36 struct AlwaysFalseHelper { 37 static constexpr bool kValue = false; 38 }; 39 40 } // namespace internal 41 42 template <typename... Args> 43 inline constexpr bool AlwaysFalse = 44 internal::AlwaysFalseHelper<Args...>::kValue; 45 46 } // namespace base 47 48 #endif // BASE_TYPES_ALWAYS_FALSE_H_ 49