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