Ticket #8336: manip.hpp.patch

File manip.hpp.patch, 2.7 KB (added by jeffrey.flinn@…, 10 years ago)

patch with thread safety fix

  • manip.hpp

     
    1111
    1212#include <boost/config.hpp>
    1313#include <string>
    14 #include <vector>
    1514#include <cctype>
    1615
    1716// Tuple I/O manipulators
     
    4645            return index;
    4746        }
    4847
    49         template <typename Stream, typename Tag, typename T>
     48        template <typename Stream, typename Tag>
    5049        struct stream_data
    5150        {
    52             struct arena
     51            typedef FUSION_STRING_OF_STREAM(Stream) string_type;
     52
     53            static void attach(Stream& s, string_type const& data)
    5354            {
    54                 ~arena()
    55                 {
    56                     for (
    57                         typename std::vector<T*>::iterator i = data.begin()
    58                       ; i != data.end()
    59                       ; ++i)
    60                     {
    61                         delete *i;
    62                     }
    63                 }
     55                delete_this(s); // last manipulator over-writes previous
    6456
    65                 std::vector<T*> data;
    66             };
     57                get_ptr_ref(s) = new string_type(data);
    6758
    68             static void attach(Stream& stream, T const& data)
     59                s.register_callback(erase, index());
     60            }
     61
     62            static string_type const* get(Stream& s)
    6963            {
    70                 static arena ar; // our arena
    71                 ar.data.push_back(new T(data));
    72                 stream.pword(get_xalloc_index<Tag>()) = ar.data.back();
     64                return get_ptr_ref(s);
    7365            }
    7466
    75             static T const* get(Stream& stream)
     67        private:
     68
     69            static int index() { return get_xalloc_index<Tag>(); }
     70
     71            static string_type const*& get_ptr_ref(std::ios_base& s)
    7672            {
    77                 return (T const*)stream.pword(get_xalloc_index<Tag>());
     73                return (string_type const*&)s.pword(index());
    7874            }
     75
     76            static void erase(std::ios_base::event ev, std::ios_base& s, int idx)
     77            {
     78                if(std::ios_base::erase_event == ev && index() == idx)
     79                {
     80                    delete_this(s);
     81                }
     82            }
     83
     84            static void delete_this(std::ios_base& s)
     85            {
     86                delete get_ptr_ref(s); get_ptr_ref(s) = 0;
     87            }
    7988        };
    8089
    8190        template <typename Tag, typename Stream>
     
    8594
    8695            typedef FUSION_STRING_OF_STREAM(Stream) string_type;
    8796
    88             typedef stream_data<Stream, Tag, string_type> stream_data_t;
     97            typedef stream_data<Stream, Tag> stream_data_t;
    8998
    9099            string_ios_manip(Stream& str_)
    91100                : stream(str_)