coroutine.hpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. //
  2. // Copyright (c) 2025 Marcelo Zimbres Silva (mzimbres@gmail.com),
  3. // Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #ifndef BOOST_REDIS_DETAIL_COROUTINE_HPP
  9. #define BOOST_REDIS_DETAIL_COROUTINE_HPP
  10. // asio::coroutine uses __COUNTER__ internally, which can trigger
  11. // ODR violations if we use them in header-only code. These manifest as
  12. // extremely hard-to-debug bugs only present in release builds.
  13. // Use this instead when doing coroutines in non-template code.
  14. // Adapted from Boost.MySQL.
  15. // Coroutine state is represented as an integer (resume_point_var).
  16. // Every yield gets assigned a unique value (resume_point_id).
  17. // Yielding sets the next resume point, returns, and sets a case label for re-entering.
  18. // Coroutines need to switch on resume_point_var to re-enter.
  19. // Enclosing this in a scope allows placing the macro inside a brace-less for/while loop
  20. // The empty scope after the case label is required because labels can't be at the end of a compound statement
  21. #define BOOST_REDIS_YIELD(resume_point_var, resume_point_id, ...) \
  22. { \
  23. resume_point_var = resume_point_id; \
  24. return {__VA_ARGS__}; \
  25. case resume_point_id: \
  26. { \
  27. } \
  28. }
  29. #define BOOST_REDIS_CORO_INITIAL case 0:
  30. #endif