Index: manip.hpp =================================================================== --- manip.hpp (revision 83587) +++ manip.hpp (working copy) @@ -11,7 +11,6 @@ #include #include -#include #include // Tuple I/O manipulators @@ -38,44 +37,72 @@ { namespace detail { - template - int get_xalloc_index(Tag* = 0) + template + struct xalloc_key_holder { - // each Tag will have a unique index - static int index = std::ios::xalloc(); - return index; - } + static int value; + static bool initialized; + }; - template - struct stream_data + template + int xalloc_key_holder::value = 0; + + template + bool xalloc_key_holder::initialized = 0; + + template + struct xalloc_key_initializer_t { - struct arena + xalloc_key_initializer_t() { - ~arena() + if (!xalloc_key_holder::initialized) { - for ( - typename std::vector::iterator i = data.begin() - ; i != data.end() - ; ++i) - { - delete *i; - } + xalloc_key_holder::value = std::ios_base::xalloc(); + xalloc_key_holder::initialized = true; } + } + }; - std::vector data; - }; + template + struct stream_data + { + typedef FUSION_STRING_OF_STREAM(Stream) string_type; - static void attach(Stream& stream, T const& data) + static void attach(Stream& s, string_type const& data) { - static arena ar; // our arena - ar.data.push_back(new T(data)); - stream.pword(get_xalloc_index()) = ar.data.back(); + delete_this(s); // last manipulator over-writes previous + + get_ptr_ref(s) = new string_type(data); + + s.register_callback(erase, index()); } - static T const* get(Stream& stream) + static string_type const* get(Stream& s) { - return (T const*)stream.pword(get_xalloc_index()); + return get_ptr_ref(s); } + + private: + + static int index() { return xalloc_key_holder::value; } + + static string_type const*& get_ptr_ref(std::ios_base& s) + { + return (string_type const*&)s.pword(index()); + } + + static void erase(std::ios_base::event ev, std::ios_base& s, int idx) + { + if(std::ios_base::erase_event == ev && index() == idx) + { + delete_this(s); + } + } + + static void delete_this(std::ios_base& s) + { + delete get_ptr_ref(s); get_ptr_ref(s) = 0; + } }; template @@ -85,7 +112,7 @@ typedef FUSION_STRING_OF_STREAM(Stream) string_type; - typedef stream_data stream_data_t; + typedef stream_data stream_data_t; string_ios_manip(Stream& str_) : stream(str_) @@ -301,6 +328,7 @@ #endif // defined(BOOST_NO_TEMPLATED_STREAMS) + STD_TUPLE_DEFINE_MANIPULATOR(tuple_open) STD_TUPLE_DEFINE_MANIPULATOR(tuple_close) STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter) @@ -309,12 +337,21 @@ STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close) STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter) + #undef STD_TUPLE_DEFINE_MANIPULATOR #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS #undef FUSION_STRING_OF_STREAM #undef FUSION_GET_CHAR_TYPE #undef FUSION_GET_TRAITS_TYPE +namespace detail { namespace /**/ { + + xalloc_key_initializer_t xalloc_key_initializer_tuple_open; + xalloc_key_initializer_t xalloc_key_initializer_tuple_close; + xalloc_key_initializer_t xalloc_key_initializer_tuple_delimiter; + +} } + }} #endif