transmogrify.hpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // transmogrify.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSMOGRIFY_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSMOGRIFY_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <cstring> // for std::strlen
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/mpl/or.hpp>
  16. #include <boost/mpl/bool.hpp>
  17. #include <boost/mpl/assert.hpp>
  18. #include <boost/type_traits/is_same.hpp>
  19. #include <boost/xpressive/detail/detail_fwd.hpp>
  20. #include <boost/xpressive/detail/core/matchers.hpp>
  21. #include <boost/xpressive/detail/static/placeholders.hpp>
  22. #include <boost/xpressive/detail/utility/dont_care.hpp>
  23. #include <boost/xpressive/detail/utility/traits_utils.hpp>
  24. namespace boost { namespace xpressive { namespace detail
  25. {
  26. template<typename T, typename Char>
  27. struct is_char_literal
  28. : mpl::or_<is_same<T, Char>, is_same<T, char> >
  29. {};
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // transmogrify
  32. //
  33. template<typename BidiIter, typename ICase, typename Traits, typename Matcher, typename EnableIf = void>
  34. struct default_transmogrify
  35. {
  36. typedef typename Traits::char_type char_type;
  37. typedef typename Traits::string_type string_type;
  38. typedef typename mpl::if_c
  39. <
  40. is_char_literal<Matcher, char_type>::value
  41. , literal_matcher<Traits, ICase, mpl::false_>
  42. , string_matcher<Traits, ICase>
  43. >::type type;
  44. template<typename Matcher2, typename Visitor>
  45. static type call(Matcher2 const &m, Visitor &visitor)
  46. {
  47. return default_transmogrify::call_(m, visitor, is_char_literal<Matcher2, char_type>());
  48. }
  49. template<typename Matcher2, typename Visitor>
  50. static type call_(Matcher2 const &m, Visitor &visitor, mpl::true_)
  51. {
  52. char_type ch = char_cast<char_type>(m, visitor.traits());
  53. return type(ch, visitor.traits());
  54. }
  55. template<typename Matcher2, typename Visitor>
  56. static type call_(Matcher2 const &m, Visitor &visitor, mpl::false_)
  57. {
  58. string_type str = string_cast<string_type>(m, visitor.traits());
  59. return type(str, visitor.traits());
  60. }
  61. };
  62. template<typename BidiIter, typename ICase, typename Traits, typename Matcher>
  63. struct default_transmogrify<BidiIter, ICase, Traits, Matcher, typename Matcher::is_boost_xpressive_xpression_>
  64. {
  65. typedef Matcher type;
  66. template<typename Matcher2>
  67. static Matcher2 const &call(Matcher2 const &m, dont_care)
  68. {
  69. return m;
  70. }
  71. };
  72. template<typename BidiIter, typename ICase, typename Traits, typename Matcher>
  73. struct transmogrify
  74. : default_transmogrify<BidiIter, ICase, Traits, Matcher>
  75. {};
  76. template<typename BidiIter, typename ICase, typename Traits>
  77. struct transmogrify<BidiIter, ICase, Traits, assert_bol_placeholder >
  78. {
  79. typedef assert_bol_matcher<Traits> type;
  80. template<typename Matcher2, typename Visitor>
  81. static type call(Matcher2, Visitor &visitor)
  82. {
  83. return type(visitor.traits());
  84. }
  85. };
  86. template<typename BidiIter, typename ICase, typename Traits>
  87. struct transmogrify<BidiIter, ICase, Traits, assert_eol_placeholder >
  88. {
  89. typedef assert_eol_matcher<Traits> type;
  90. template<typename Matcher2, typename Visitor>
  91. static type call(Matcher2, Visitor &visitor)
  92. {
  93. return type(visitor.traits());
  94. }
  95. };
  96. template<typename BidiIter, typename ICase, typename Traits>
  97. struct transmogrify<BidiIter, ICase, Traits, logical_newline_placeholder >
  98. {
  99. typedef logical_newline_matcher<Traits> type;
  100. template<typename Matcher2, typename Visitor>
  101. static type call(Matcher2, Visitor &visitor)
  102. {
  103. return type(visitor.traits());
  104. }
  105. };
  106. template<typename BidiIter, typename ICase, typename Traits, typename Char>
  107. struct transmogrify<BidiIter, ICase, Traits, range_placeholder<Char> >
  108. {
  109. // By design, we don't widen character ranges.
  110. typedef typename iterator_value<BidiIter>::type char_type;
  111. BOOST_MPL_ASSERT((is_same<Char, char_type>));
  112. typedef range_matcher<Traits, ICase> type;
  113. template<typename Matcher2, typename Visitor>
  114. static type call(Matcher2 const &m, Visitor &visitor)
  115. {
  116. return type(m.ch_min_, m.ch_max_, m.not_, visitor.traits());
  117. }
  118. };
  119. template<typename BidiIter, typename ICase, typename Traits>
  120. struct transmogrify<BidiIter, ICase, Traits, mark_placeholder >
  121. {
  122. typedef mark_matcher<Traits, ICase> type;
  123. template<typename Matcher2, typename Visitor>
  124. static type call(Matcher2 const &m, Visitor &visitor)
  125. {
  126. return type(m.mark_number_, visitor.traits());
  127. }
  128. };
  129. template<typename BidiIter, typename ICase, typename Traits>
  130. struct transmogrify<BidiIter, ICase, Traits, posix_charset_placeholder >
  131. {
  132. typedef posix_charset_matcher<Traits> type;
  133. template<typename Matcher2, typename Visitor>
  134. static type call(Matcher2 const &m, Visitor &visitor)
  135. {
  136. char const *name_end = m.name_ + std::strlen(m.name_);
  137. return type(visitor.traits().lookup_classname(m.name_, name_end, ICase::value), m.not_);
  138. }
  139. };
  140. template<typename BidiIter, typename Traits, typename Size>
  141. struct transmogrify<BidiIter, mpl::true_, Traits, set_matcher<Traits, Size> >
  142. {
  143. typedef set_matcher<Traits, Size> type;
  144. template<typename Matcher2, typename Visitor>
  145. static type call(Matcher2 m, Visitor &visitor)
  146. {
  147. m.nocase(visitor.traits());
  148. return m;
  149. }
  150. };
  151. template<typename BidiIter, typename ICase, typename Traits, typename Cond>
  152. struct transmogrify<BidiIter, ICase, Traits, assert_word_placeholder<Cond> >
  153. {
  154. typedef assert_word_matcher<Cond, Traits> type;
  155. template<typename Visitor>
  156. static type call(dont_care, Visitor &visitor)
  157. {
  158. return type(visitor.traits());
  159. }
  160. };
  161. template<typename BidiIter, typename ICase, typename Traits>
  162. struct transmogrify<BidiIter, ICase, Traits, reference_wrapper<basic_regex<BidiIter> > >
  163. {
  164. typedef regex_byref_matcher<BidiIter> type;
  165. template<typename Matcher2>
  166. static type call(Matcher2 const &m, dont_care)
  167. {
  168. return type(detail::core_access<BidiIter>::get_regex_impl(m.get()));
  169. }
  170. };
  171. template<typename BidiIter, typename ICase, typename Traits>
  172. struct transmogrify<BidiIter, ICase, Traits, reference_wrapper<basic_regex<BidiIter> const> >
  173. {
  174. typedef regex_byref_matcher<BidiIter> type;
  175. template<typename Matcher2>
  176. static type call(Matcher2 const &m, dont_care)
  177. {
  178. return type(detail::core_access<BidiIter>::get_regex_impl(m.get()));
  179. }
  180. };
  181. template<typename BidiIter, typename ICase, typename Traits>
  182. struct transmogrify<BidiIter, ICase, Traits, tracking_ptr<regex_impl<BidiIter> > >
  183. {
  184. typedef regex_matcher<BidiIter> type;
  185. template<typename Matcher2>
  186. static type call(Matcher2 const &m, dont_care)
  187. {
  188. return type(m.get());
  189. }
  190. };
  191. template<typename BidiIter, typename ICase, typename Traits>
  192. struct transmogrify<BidiIter, ICase, Traits, self_placeholder >
  193. {
  194. typedef regex_byref_matcher<BidiIter> type;
  195. template<typename Matcher2, typename Visitor>
  196. static type call(Matcher2, Visitor &visitor)
  197. {
  198. return type(visitor.self());
  199. }
  200. };
  201. }}}
  202. #endif