Ticket #8336: manip.hpp.2.patch
File manip.hpp.2.patch, 4.5 KB (added by , 10 years ago) |
---|
-
manip.hpp
11 11 12 12 #include <boost/config.hpp> 13 13 #include <string> 14 #include <vector>15 14 #include <cctype> 16 15 17 16 // Tuple I/O manipulators … … 38 37 { 39 38 namespace detail 40 39 { 41 template 42 int get_xalloc_index(Tag* = 0)40 template<typename Tag> 41 struct xalloc_key_holder 43 42 { 44 // each Tag will have a unique index 45 static int index = std::ios::xalloc(); 46 return index; 47 } 43 static int value; 44 static bool initialized; 45 }; 48 46 49 template <typename Stream, typename Tag, typename T> 50 struct stream_data 47 template<typename Tag> 48 int xalloc_key_holder<Tag>::value = 0; 49 50 template<typename Tag> 51 bool xalloc_key_holder<Tag>::initialized = 0; 52 53 template<typename Tag> 54 struct xalloc_key_initializer_t 51 55 { 52 struct arena56 xalloc_key_initializer_t() 53 57 { 54 ~arena()58 if (!xalloc_key_holder<Tag>::initialized) 55 59 { 56 for ( 57 typename std::vector<T*>::iterator i = data.begin() 58 ; i != data.end() 59 ; ++i) 60 { 61 delete *i; 62 } 60 xalloc_key_holder<Tag>::value = std::ios_base::xalloc(); 61 xalloc_key_holder<Tag>::initialized = true; 63 62 } 63 } 64 }; 64 65 65 std::vector<T*> data; 66 }; 66 template <typename Stream, typename Tag> 67 struct stream_data 68 { 69 typedef FUSION_STRING_OF_STREAM(Stream) string_type; 67 70 68 static void attach(Stream& s tream, Tconst& data)71 static void attach(Stream& s, string_type const& data) 69 72 { 70 static arena ar; // our arena 71 ar.data.push_back(new T(data)); 72 stream.pword(get_xalloc_index<Tag>()) = ar.data.back(); 73 delete_this(s); // last manipulator over-writes previous 74 75 get_ptr_ref(s) = new string_type(data); 76 77 s.register_callback(erase, index()); 73 78 } 74 79 75 static T const* get(Stream& stream)80 static string_type const* get(Stream& s) 76 81 { 77 return (T const*)stream.pword(get_xalloc_index<Tag>());82 return get_ptr_ref(s); 78 83 } 84 85 private: 86 87 static int index() { return xalloc_key_holder<Tag>::value; } 88 89 static string_type const*& get_ptr_ref(std::ios_base& s) 90 { 91 return (string_type const*&)s.pword(index()); 92 } 93 94 static void erase(std::ios_base::event ev, std::ios_base& s, int idx) 95 { 96 if(std::ios_base::erase_event == ev && index() == idx) 97 { 98 delete_this(s); 99 } 100 } 101 102 static void delete_this(std::ios_base& s) 103 { 104 delete get_ptr_ref(s); get_ptr_ref(s) = 0; 105 } 79 106 }; 80 107 81 108 template <typename Tag, typename Stream> … … 85 112 86 113 typedef FUSION_STRING_OF_STREAM(Stream) string_type; 87 114 88 typedef stream_data<Stream, Tag , string_type> stream_data_t;115 typedef stream_data<Stream, Tag> stream_data_t; 89 116 90 117 string_ios_manip(Stream& str_) 91 118 : stream(str_) … … 301 328 302 329 #endif // defined(BOOST_NO_TEMPLATED_STREAMS) 303 330 331 304 332 STD_TUPLE_DEFINE_MANIPULATOR(tuple_open) 305 333 STD_TUPLE_DEFINE_MANIPULATOR(tuple_close) 306 334 STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter) … … 309 337 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close) 310 338 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter) 311 339 340 312 341 #undef STD_TUPLE_DEFINE_MANIPULATOR 313 342 #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS 314 343 #undef FUSION_STRING_OF_STREAM 315 344 #undef FUSION_GET_CHAR_TYPE 316 345 #undef FUSION_GET_TRAITS_TYPE 317 346 347 namespace detail { namespace /**/ { 348 349 xalloc_key_initializer_t<tuple_open_tag > xalloc_key_initializer_tuple_open; 350 xalloc_key_initializer_t<tuple_close_tag > xalloc_key_initializer_tuple_close; 351 xalloc_key_initializer_t<tuple_delimiter_tag> xalloc_key_initializer_tuple_delimiter; 352 353 } } 354 318 355 }} 319 356 320 357 #endif