macros.hh 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file macros.hh
  3. /// @brief Fundamental macros and types.
  4. // (c) Daniel Llorens - 2005, 2012, 2019-2020
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #pragma once
  10. #include <cstddef>
  11. #include <cassert>
  12. #include <type_traits>
  13. #include <utility>
  14. #define STRINGIZE_( x ) #x
  15. #define STRINGIZE( x ) STRINGIZE_( x )
  16. #define JOIN_( x, y ) x##y
  17. #define JOIN( x, y ) JOIN_( x, y )
  18. // by G. Pakosz @ http://stackoverflow.com/a/1872506
  19. #define FOR_EACH_1(what, x, ...) what(x)
  20. #define FOR_EACH_2(what, x, ...) what(x) FOR_EACH_1(what, __VA_ARGS__)
  21. #define FOR_EACH_3(what, x, ...) what(x) FOR_EACH_2(what, __VA_ARGS__)
  22. #define FOR_EACH_4(what, x, ...) what(x) FOR_EACH_3(what, __VA_ARGS__)
  23. #define FOR_EACH_5(what, x, ...) what(x) FOR_EACH_4(what, __VA_ARGS__)
  24. #define FOR_EACH_6(what, x, ...) what(x) FOR_EACH_5(what, __VA_ARGS__)
  25. #define FOR_EACH_7(what, x, ...) what(x) FOR_EACH_6(what, __VA_ARGS__)
  26. #define FOR_EACH_8(what, x, ...) what(x) FOR_EACH_7(what, __VA_ARGS__)
  27. #define FOR_EACH_9(what, x, ...) what(x) FOR_EACH_8(what, __VA_ARGS__)
  28. #define FOR_EACH_10(what, x, ...) what(x) FOR_EACH_9(what, __VA_ARGS__)
  29. #define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
  30. #define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
  31. #define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
  32. #define FOR_EACH_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
  33. #define FOR_EACH_(N, what, ...) JOIN(FOR_EACH_, N)(what, __VA_ARGS__)
  34. #define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
  35. // https://en.cppreference.com/w/cpp/preprocessor/replace
  36. // See examples/throw.cc for the way to override this RA_ASSERT.
  37. #ifndef RA_ASSERT
  38. #define RA_ASSERT(cond, ...) assert(cond)
  39. #endif
  40. #if defined(RA_DO_CHECK) && RA_DO_CHECK==0
  41. #define RA_CHECK( ... )
  42. #else
  43. #define RA_CHECK( ... ) RA_ASSERT( __VA_ARGS__ )
  44. #endif
  45. namespace mp {
  46. #define RA_IS_DEF(NAME, PRED) \
  47. template <class A> constexpr bool JOIN(NAME, _def) = false; \
  48. template <class A> requires (PRED) constexpr bool JOIN(NAME, _def) < A > = true; \
  49. template <class A> constexpr bool NAME = JOIN(NAME, _def)< std::decay_t< A >>;
  50. // Assign ops for settable array iterators; these must be members.
  51. // For containers & views this might be defined differently.
  52. // forward to make sure value y is not misused as ref [ra05].
  53. #define RA_DEF_ASSIGNOPS(OP) \
  54. template <class X> constexpr void operator OP(X && x) \
  55. { for_each([](auto && y, auto && x) { std::forward<decltype(y)>(y) OP x; }, *this, x); }
  56. } // namespace mp