configor_wrapper.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright (c) 2018-2021 configor - Nomango
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. #pragma once
  21. #include "configor_parser.hpp"
  22. #include "configor_serializer.hpp"
  23. namespace configor
  24. {
  25. namespace detail
  26. {
  27. template <typename _ConfigTy, typename _Ty>
  28. class ostream_wrapper
  29. {
  30. public:
  31. using config_type = _ConfigTy;
  32. using value_type = typename _ConfigTy::value;
  33. explicit ostream_wrapper(const _Ty& v)
  34. : v_(v)
  35. {
  36. }
  37. template <typename _TargetCharTy, typename _Traits>
  38. friend std::basic_ostream<_TargetCharTy, _Traits>& operator<<(std::basic_ostream<_TargetCharTy, _Traits>& out,
  39. const ostream_wrapper& wrapper)
  40. {
  41. typename std::basic_ostream<_TargetCharTy, _Traits>::sentry s(out);
  42. if (s)
  43. {
  44. config_type::dump(out, static_cast<value_type>(wrapper.v_));
  45. }
  46. return out;
  47. }
  48. private:
  49. const _Ty& v_;
  50. };
  51. template <typename _ConfigTy, typename _Args>
  52. class ostream_wrapper<_ConfigTy, basic_value<_Args>>
  53. {
  54. public:
  55. using config_type = _ConfigTy;
  56. using value_type = typename _ConfigTy::value;
  57. explicit ostream_wrapper(const value_type& v)
  58. : v_(v)
  59. {
  60. }
  61. template <typename _TargetCharTy, typename _Traits>
  62. friend std::basic_ostream<_TargetCharTy, _Traits>& operator<<(std::basic_ostream<_TargetCharTy, _Traits>& out,
  63. const ostream_wrapper& wrapper)
  64. {
  65. typename std::basic_ostream<_TargetCharTy, _Traits>::sentry s(out);
  66. if (s)
  67. {
  68. config_type::dump(out, wrapper.v_);
  69. }
  70. return out;
  71. }
  72. private:
  73. const value_type& v_;
  74. };
  75. template <typename _ConfigTy, typename _Ty>
  76. class iostream_wrapper : public ostream_wrapper<_ConfigTy, _Ty>
  77. {
  78. public:
  79. using config_type = _ConfigTy;
  80. using value_type = typename _ConfigTy::value;
  81. explicit iostream_wrapper(_Ty& v)
  82. : ostream_wrapper<_ConfigTy, _Ty>(v)
  83. , v_(v)
  84. {
  85. }
  86. template <typename _SourceCharTy, typename _Traits>
  87. friend std::basic_istream<_SourceCharTy, _Traits>&
  88. operator>>(std::basic_istream<_SourceCharTy, _Traits>& in,
  89. const iostream_wrapper& wrapper /* wrapper must be lvalue */)
  90. {
  91. typename std::basic_istream<_SourceCharTy, _Traits>::sentry s(in);
  92. if (s)
  93. {
  94. value_type c{};
  95. config_type::parse(c, in);
  96. const_cast<_Ty&>(wrapper.v_) = c.template get<_Ty>();
  97. }
  98. return in;
  99. }
  100. private:
  101. _Ty& v_;
  102. };
  103. template <typename _ConfigTy, typename _Args>
  104. class iostream_wrapper<_ConfigTy, basic_value<_Args>> : public ostream_wrapper<_ConfigTy, basic_value<_Args>>
  105. {
  106. public:
  107. using config_type = _ConfigTy;
  108. using value_type = typename _ConfigTy::value;
  109. explicit iostream_wrapper(value_type& v)
  110. : ostream_wrapper<_ConfigTy, value_type>(v)
  111. , v_(v)
  112. {
  113. }
  114. template <typename _SourceCharTy, typename _Traits>
  115. friend std::basic_istream<_SourceCharTy, _Traits>&
  116. operator>>(std::basic_istream<_SourceCharTy, _Traits>& in,
  117. const iostream_wrapper& wrapper /* wrapper must be lvalue */)
  118. {
  119. typename std::basic_istream<_SourceCharTy, _Traits>::sentry s(in);
  120. if (s)
  121. {
  122. config_type::parse(const_cast<value_type&>(wrapper.v_), in);
  123. }
  124. return in;
  125. }
  126. private:
  127. value_type& v_;
  128. };
  129. template <typename _ConfigTy, typename _ValTy>
  130. class iostream_wrapper_maker
  131. {
  132. public:
  133. using config_type = _ConfigTy;
  134. using value_type = _ValTy;
  135. template <typename _Ty, typename = typename std::enable_if<std::is_same<value_type, _Ty>::value
  136. || has_to_value<value_type, _Ty>::value>::type>
  137. static inline ostream_wrapper<config_type, _Ty> wrap(const _Ty& v)
  138. {
  139. return ostream_wrapper<config_type, _Ty>(v);
  140. }
  141. template <typename _Ty, typename = typename std::enable_if<(std::is_same<value_type, _Ty>::value
  142. || is_value_getable<value_type, _Ty>::value)
  143. && !std::is_pointer<_Ty>::value>::type>
  144. static inline iostream_wrapper<config_type, _Ty> wrap(_Ty& v)
  145. {
  146. return iostream_wrapper<config_type, _Ty>(v);
  147. }
  148. };
  149. } // namespace detail
  150. } // namespace configor