user_data_cp.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_USER_DATA_COMPONENT_HPP__
  11. #define __ASIO2_USER_DATA_COMPONENT_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <any>
  16. #include <asio2/base/error.hpp>
  17. namespace asio2::detail
  18. {
  19. template<class derived_t, class args_t = void>
  20. class user_data_cp
  21. {
  22. public:
  23. /**
  24. * @brief constructor
  25. */
  26. user_data_cp() = default;
  27. /**
  28. * @brief destructor
  29. */
  30. ~user_data_cp() = default;
  31. user_data_cp(user_data_cp&&) noexcept = default;
  32. user_data_cp(user_data_cp const&) = default;
  33. user_data_cp& operator=(user_data_cp&&) noexcept = default;
  34. user_data_cp& operator=(user_data_cp const&) = default;
  35. public:
  36. /**
  37. * @brief set user data, internal use std::any to storage, you can set any type of data
  38. * same as set_user_data
  39. */
  40. template<class DataT>
  41. [[deprecated("Replace user_data with set_user_data")]]
  42. inline derived_t & user_data(DataT && data)
  43. {
  44. return this->set_user_data(std::forward<DataT>(data));
  45. }
  46. /**
  47. * @brief get user data, same as get_user_data
  48. * example : MyStruct my = user_data<MyStruct>(); MyStruct* my = user_data<MyStruct*>();
  49. */
  50. template<class DataT>
  51. [[deprecated("Replace user_data with get_user_data")]]
  52. inline DataT user_data() noexcept
  53. {
  54. return this->get_user_data<DataT>();
  55. }
  56. /**
  57. * @brief set user data, internal use std::any to storage, you can set any type of data
  58. * example : struct MyStruct{ ... }; MyStruct my; set_user_data(my);
  59. */
  60. template<class DataT>
  61. inline derived_t & set_user_data(DataT && data)
  62. {
  63. this->user_data_ = std::forward<DataT>(data);
  64. return (static_cast<derived_t &>(*this));
  65. }
  66. /**
  67. * @brief get user data
  68. * example :
  69. * MyStruct my = get_user_data<MyStruct>();
  70. * MyStruct* my = get_user_data<MyStruct*>();
  71. * MyStruct& my = get_user_data<MyStruct&>();
  72. */
  73. template<class DataT>
  74. inline DataT get_user_data() noexcept
  75. {
  76. if constexpr (std::is_reference_v<DataT>)
  77. {
  78. typename std::add_pointer_t<std::remove_reference_t<DataT>> r =
  79. std::any_cast<std::remove_reference_t<DataT>>(std::addressof(this->user_data_));
  80. if (r)
  81. {
  82. return (*r);
  83. }
  84. else
  85. {
  86. static typename std::remove_reference_t<DataT> st{};
  87. return st;
  88. }
  89. }
  90. else if constexpr (std::is_pointer_v<DataT>)
  91. {
  92. // user_data_ is pointer, and DataT is pointer too.
  93. if (this->user_data_.type() == typeid(DataT))
  94. return std::any_cast<DataT>(this->user_data_);
  95. // user_data_ is not pointer, but DataT is pointer.
  96. return std::any_cast<std::remove_pointer_t<DataT>>(std::addressof(this->user_data_));
  97. }
  98. else
  99. {
  100. #if !defined(ASIO_NO_EXCEPTIONS) && !defined(BOOST_ASIO_NO_EXCEPTIONS)
  101. try
  102. {
  103. #endif
  104. return std::any_cast<DataT>(this->user_data_);
  105. #if !defined(ASIO_NO_EXCEPTIONS) && !defined(BOOST_ASIO_NO_EXCEPTIONS)
  106. }
  107. catch (const std::bad_any_cast&)
  108. {
  109. if (this->user_data_.has_value())
  110. {
  111. ASIO2_ASSERT(false);
  112. }
  113. }
  114. return DataT{};
  115. #endif
  116. }
  117. }
  118. /**
  119. * @brief clear user data
  120. */
  121. inline derived_t& clear_user_data() noexcept
  122. {
  123. this->user_data_.reset();
  124. return (static_cast<derived_t&>(*this));
  125. }
  126. /**
  127. * @brief return the std::any reference
  128. */
  129. inline std::any& user_data_any() noexcept { return this->user_data_; }
  130. /**
  131. * @brief return the std::any reference
  132. */
  133. inline std::any const& user_data_any() const noexcept { return this->user_data_; }
  134. protected:
  135. /// user data
  136. std::any user_data_;
  137. };
  138. }
  139. #endif // !__ASIO2_USER_DATA_COMPONENT_HPP__