Ticket #8336: manip.hpp.2.patch

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

updated patch replacing local static initialization with C++03 class static initialization

  • manip.hpp

     
    1111
    1212#include <boost/config.hpp>
    1313#include <string>
    14 #include <vector>
    1514#include <cctype>
    1615
    1716// Tuple I/O manipulators
     
    3837{
    3938    namespace detail
    4039    {
    41         template <typename Tag>
    42         int get_xalloc_index(Tag* = 0)
     40        template<typename Tag>
     41        struct xalloc_key_holder
    4342        {
    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        };
    4846
    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
    5155        {
    52             struct arena
     56            xalloc_key_initializer_t()
    5357            {
    54                 ~arena()
     58                if (!xalloc_key_holder<Tag>::initialized)
    5559                {
    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;
    6362                }
     63            }
     64        };
    6465
    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;
    6770
    68             static void attach(Stream& stream, T const& data)
     71            static void attach(Stream& s, string_type const& data)
    6972            {
    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());
    7378            }
    7479
    75             static T const* get(Stream& stream)
     80            static string_type const* get(Stream& s)
    7681            {
    77                 return (T const*)stream.pword(get_xalloc_index<Tag>());
     82                return get_ptr_ref(s);
    7883            }
     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            }
    79106        };
    80107
    81108        template <typename Tag, typename Stream>
     
    85112
    86113            typedef FUSION_STRING_OF_STREAM(Stream) string_type;
    87114
    88             typedef stream_data<Stream, Tag, string_type> stream_data_t;
     115            typedef stream_data<Stream, Tag> stream_data_t;
    89116
    90117            string_ios_manip(Stream& str_)
    91118                : stream(str_)
     
    301328
    302329#endif // defined(BOOST_NO_TEMPLATED_STREAMS)
    303330
     331
    304332    STD_TUPLE_DEFINE_MANIPULATOR(tuple_open)
    305333    STD_TUPLE_DEFINE_MANIPULATOR(tuple_close)
    306334    STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter)
     
    309337    STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close)
    310338    STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter)
    311339
     340
    312341#undef STD_TUPLE_DEFINE_MANIPULATOR
    313342#undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS
    314343#undef FUSION_STRING_OF_STREAM
    315344#undef FUSION_GET_CHAR_TYPE
    316345#undef FUSION_GET_TRAITS_TYPE
    317346
     347namespace 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
    318355}}
    319356
    320357#endif