metaprogramming.h 1.2 KB

12345678910111213141516171819202122232425262728293031323334
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef COMMON_METAPROGRAMMING_H_
  5. #define COMMON_METAPROGRAMMING_H_
  6. #include <type_traits>
  7. namespace Carbon {
  8. // C++17-compatible emulation of a C++20 `requires` expression, which queries
  9. // whether a given expression is well-formed. The syntax is best explained
  10. // in terms of an example:
  11. //
  12. // template <typename T>
  13. // static constexpr bool IsStreamableToRawOstream =
  14. // Requires<const T, llvm::raw_ostream>(
  15. // [](auto&& t, auto&& out) -> decltype(out << t) {});
  16. //
  17. // The expression enclosed in `decltype` is the expression whose validity the
  18. // trait queries. The lambda parameters declare the names that are used in
  19. // that expression, and the types of those names are specified by the
  20. // corresponding template arguments of the `Requires` call. The lambda
  21. // parameters should always have type `auto&&`, and the template arguments
  22. // should not have `&` or `&&` qualifiers.
  23. template <typename... T, typename F>
  24. constexpr auto Requires(F /* f */) -> bool {
  25. return std::is_invocable_v<F, T...>;
  26. }
  27. } // namespace Carbon
  28. #endif // COMMON_METAPROGRAMMING_H_