manip.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*=============================================================================
  2. Copyright (c) 1999-2003 Jeremiah Willcock
  3. Copyright (c) 1999-2003 Jaakko Jarvi
  4. Copyright (c) 2001-2011 Joel de Guzman
  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. #if !defined(FUSION_MANIP_05052005_1200)
  9. #define FUSION_MANIP_05052005_1200
  10. #include <boost/config.hpp>
  11. #include <string>
  12. #include <vector>
  13. #include <cctype>
  14. // Tuple I/O manipulators
  15. #define FUSION_GET_CHAR_TYPE(T) typename T::char_type
  16. #define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type
  17. #if defined (BOOST_NO_TEMPLATED_STREAMS)
  18. #define FUSION_STRING_OF_STREAM(Stream) std::string
  19. #else
  20. #define FUSION_STRING_OF_STREAM(Stream) \
  21. std::basic_string< \
  22. FUSION_GET_CHAR_TYPE(Stream) \
  23. , FUSION_GET_TRAITS_TYPE(Stream) \
  24. >
  25. #endif
  26. //$$$ these should be part of the public API$$$
  27. //$$$ rename tuple_open, tuple_close and tuple_delimiter to
  28. // open, close and delimeter and add these synonyms to the
  29. // TR1 tuple module.
  30. namespace boost { namespace fusion
  31. {
  32. namespace detail
  33. {
  34. template <typename Tag>
  35. int get_xalloc_index(Tag* = 0)
  36. {
  37. // each Tag will have a unique index
  38. static int index = std::ios::xalloc();
  39. return index;
  40. }
  41. template <typename Stream, typename Tag, typename T>
  42. struct stream_data
  43. {
  44. struct arena
  45. {
  46. ~arena()
  47. {
  48. for (
  49. typename std::vector<T*>::iterator i = data.begin()
  50. ; i != data.end()
  51. ; ++i)
  52. {
  53. delete *i;
  54. }
  55. }
  56. std::vector<T*> data;
  57. };
  58. static void attach(Stream& stream, T const& data)
  59. {
  60. static arena ar; // our arena
  61. ar.data.push_back(new T(data));
  62. stream.pword(get_xalloc_index<Tag>()) = ar.data.back();
  63. }
  64. static T const* get(Stream& stream)
  65. {
  66. return (T const*)stream.pword(get_xalloc_index<Tag>());
  67. }
  68. };
  69. template <typename Tag, typename Stream>
  70. class string_ios_manip
  71. {
  72. public:
  73. typedef FUSION_STRING_OF_STREAM(Stream) string_type;
  74. typedef stream_data<Stream, Tag, string_type> stream_data_t;
  75. string_ios_manip(Stream& str_)
  76. : stream(str_)
  77. {}
  78. void
  79. set(string_type const& s)
  80. {
  81. stream_data_t::attach(stream, s);
  82. }
  83. void
  84. print(char const* default_) const
  85. {
  86. // print a delimiter
  87. string_type const* p = stream_data_t::get(stream);
  88. if (p)
  89. stream << *p;
  90. else
  91. stream << default_;
  92. }
  93. void
  94. read(char const* default_) const
  95. {
  96. // read a delimiter
  97. string_type const* p = stream_data_t::get(stream);
  98. using namespace std;
  99. ws(stream);
  100. if (p)
  101. {
  102. typedef typename string_type::const_iterator iterator;
  103. for (iterator i = p->begin(); i != p->end(); ++i)
  104. check_delim(*i);
  105. }
  106. else
  107. {
  108. while (*default_)
  109. check_delim(*default_++);
  110. }
  111. }
  112. private:
  113. template <typename Char>
  114. void
  115. check_delim(Char c) const
  116. {
  117. if (!isspace(c))
  118. {
  119. if (stream.get() != c)
  120. {
  121. stream.unget();
  122. stream.setstate(std::ios::failbit);
  123. }
  124. }
  125. }
  126. Stream& stream;
  127. private:
  128. // silence MSVC warning C4512: assignment operator could not be generated
  129. string_ios_manip& operator= (string_ios_manip const&);
  130. };
  131. } // detail
  132. #if defined (BOOST_NO_TEMPLATED_STREAMS)
  133. #define STD_TUPLE_DEFINE_MANIPULATOR(name) \
  134. namespace detail \
  135. { \
  136. struct name##_tag; \
  137. \
  138. struct name##_type \
  139. { \
  140. typedef std::string string_type; \
  141. string_type data; \
  142. name##_type(const string_type& d): data(d) {} \
  143. }; \
  144. \
  145. template <typename Stream> \
  146. Stream& operator>>(Stream& s, const name##_type& m) \
  147. { \
  148. string_ios_manip<name##_tag, Stream>(s).set(m.data); \
  149. return s; \
  150. } \
  151. \
  152. template <typename Stream> \
  153. Stream& operator<<(Stream& s, const name##_type& m) \
  154. { \
  155. string_ios_manip<name##_tag, Stream>(s).set(m.data); \
  156. return s; \
  157. } \
  158. }
  159. #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
  160. inline detail::name##_type \
  161. name(const std::string& s) \
  162. { \
  163. return detail::name##_type(s); \
  164. } \
  165. \
  166. inline detail::name##_type \
  167. name(const char* s) \
  168. { \
  169. return detail::name##_type(std::string(s)); \
  170. } \
  171. \
  172. inline detail::name##_type \
  173. name(char c) \
  174. { \
  175. return detail::name##_type(std::string(1, c)); \
  176. }
  177. #else // defined(BOOST_NO_TEMPLATED_STREAMS)
  178. #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  179. #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
  180. template <typename Char, typename Traits> \
  181. inline detail::name##_type<Char, Traits> \
  182. name(const std::basic_string<Char, Traits>& s) \
  183. { \
  184. return detail::name##_type<Char, Traits>(s); \
  185. } \
  186. \
  187. inline detail::name##_type<char> \
  188. name(char const* s) \
  189. { \
  190. return detail::name##_type<char>(std::basic_string<char>(s)); \
  191. } \
  192. \
  193. inline detail::name##_type<wchar_t> \
  194. name(wchar_t const* s) \
  195. { \
  196. return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(s)); \
  197. } \
  198. \
  199. inline detail::name##_type<char> \
  200. name(char c) \
  201. { \
  202. return detail::name##_type<char>(std::basic_string<char>(1, c)); \
  203. } \
  204. \
  205. inline detail::name##_type<wchar_t> \
  206. name(wchar_t c) \
  207. { \
  208. return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(1, c)); \
  209. }
  210. #else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  211. #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
  212. template <typename Char, typename Traits> \
  213. inline detail::name##_type<Char, Traits> \
  214. name(const std::basic_string<Char, Traits>& s) \
  215. { \
  216. return detail::name##_type<Char, Traits>(s); \
  217. } \
  218. \
  219. template <typename Char> \
  220. inline detail::name##_type<Char> \
  221. name(Char s[]) \
  222. { \
  223. return detail::name##_type<Char>(std::basic_string<Char>(s)); \
  224. } \
  225. \
  226. template <typename Char> \
  227. inline detail::name##_type<Char> \
  228. name(Char const s[]) \
  229. { \
  230. return detail::name##_type<Char>(std::basic_string<Char>(s)); \
  231. } \
  232. \
  233. template <typename Char> \
  234. inline detail::name##_type<Char> \
  235. name(Char c) \
  236. { \
  237. return detail::name##_type<Char>(std::basic_string<Char>(1, c)); \
  238. }
  239. #endif
  240. #define STD_TUPLE_DEFINE_MANIPULATOR(name) \
  241. namespace detail \
  242. { \
  243. struct name##_tag; \
  244. \
  245. template <typename Char, typename Traits = std::char_traits<Char> > \
  246. struct name##_type \
  247. { \
  248. typedef std::basic_string<Char, Traits> string_type; \
  249. string_type data; \
  250. name##_type(const string_type& d): data(d) {} \
  251. }; \
  252. \
  253. template <typename Stream, typename Char, typename Traits> \
  254. Stream& operator>>(Stream& s, const name##_type<Char,Traits>& m) \
  255. { \
  256. string_ios_manip<name##_tag, Stream>(s).set(m.data); \
  257. return s; \
  258. } \
  259. \
  260. template <typename Stream, typename Char, typename Traits> \
  261. Stream& operator<<(Stream& s, const name##_type<Char,Traits>& m) \
  262. { \
  263. string_ios_manip<name##_tag, Stream>(s).set(m.data); \
  264. return s; \
  265. } \
  266. } \
  267. #endif // defined(BOOST_NO_TEMPLATED_STREAMS)
  268. STD_TUPLE_DEFINE_MANIPULATOR(tuple_open)
  269. STD_TUPLE_DEFINE_MANIPULATOR(tuple_close)
  270. STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter)
  271. STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open)
  272. STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close)
  273. STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter)
  274. #undef STD_TUPLE_DEFINE_MANIPULATOR
  275. #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS
  276. #undef FUSION_STRING_OF_STREAM
  277. #undef FUSION_GET_CHAR_TYPE
  278. #undef FUSION_GET_TRAITS_TYPE
  279. }}
  280. #endif