1 //
2 //  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOST_SRC_LOCALE_IOS_PROP_HPP
9 #define BOOST_SRC_LOCALE_IOS_PROP_HPP
10 #include <ios>
11 
12 namespace boost {
13     namespace locale {
14         namespace impl {
15 
16             template<typename Property>
17             class ios_prop {
18             public:
set(Property const & prop,std::ios_base & ios)19                 static void set(Property const &prop,std::ios_base &ios)
20                 {
21                     int id=get_id();
22                     if(ios.pword(id)==0) {
23                         ios.pword(id) = new Property(prop);
24                         ios.register_callback(callback,id);
25                     }
26                     else if(ios.pword(id)==invalid) {
27                         ios.pword(id) = new Property(prop);
28                     }
29                     else {
30                         *static_cast<Property *>(ios.pword(id))=prop;
31                     }
32                 }
33 
get(std::ios_base & ios)34                 static Property &get(std::ios_base &ios)
35                 {
36                     int id=get_id();
37                     if(!has(ios))
38                         set(Property(),ios);
39                     return *static_cast<Property *>(ios.pword(id));
40                 }
41 
has(std::ios_base & ios)42                 static bool has(std::ios_base &ios)
43                 {
44                     int id=get_id();
45                     if(ios.pword(id)==0 || ios.pword(id)==invalid)
46                         return false;
47                     return true;
48                 }
49 
unset(std::ios_base & ios)50                 static void unset(std::ios_base &ios)
51                 {
52                     if(has(ios)) {
53                         int id=get_id();
54                         Property *p=static_cast<Property *>(ios.pword(id));
55                         delete p;
56                         ios.pword(id)=invalid;
57                     }
58                 }
global_init()59                 static void global_init()
60                 {
61                     get_id();
62                 }
63             private:
64                 static void * const invalid;
65 
callback(std::ios_base::event ev,std::ios_base & ios,int id)66                 static void callback(std::ios_base::event ev,std::ios_base &ios,int id)
67                 {
68                     switch(ev) {
69                     case std::ios_base::erase_event:
70                         if(!has(ios))
71                             break;
72                         delete reinterpret_cast<Property *>(ios.pword(id));
73                         break;
74                     case std::ios_base::copyfmt_event:
75                         if(ios.pword(id)==invalid || ios.pword(id)==0)
76                             break;
77                         ios.pword(id)=new Property(*reinterpret_cast<Property *>(ios.pword(id)));
78                         break;
79                     case std::ios_base::imbue_event:
80                         if(ios.pword(id)==invalid || ios.pword(id)==0)
81                             break;
82                         reinterpret_cast<Property *>(ios.pword(id))->on_imbue();
83                         break;
84 
85                     default: ;
86                     }
87                 }
get_id()88                 static int get_id()
89                 {
90                     static int id = std::ios_base::xalloc();
91                     return id;
92                 }
93             };
94 
95             template<typename Property>
96             void * const ios_prop<Property>::invalid = (void *)(-1);
97 
98 
99 
100         }
101     }
102 }
103 
104 
105 
106 #endif
107 
108 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
109 
110