• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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