1//
2// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3// Copyright (c) 2022 Alexander Grund
4//
5// Distributed under the Boost Software License, Version 1.0.
6// https://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
11#include <boost/locale/config.hpp>
12#include <boost/assert.hpp>
13#include <ios>
14
15namespace boost { namespace locale { namespace impl {
16
17 template<typename Property>
18 class BOOST_SYMBOL_VISIBLE ios_prop {
19 public:
20 static Property& get(std::ios_base& ios)
21 {
22 Property* result = get_impl(ios);
23 return result ? *result : create(ios);
24 }
25
26 static void global_init() { get_id(); }
27
28 private:
29 static Property* get_impl(std::ios_base& ios) { return static_cast<Property*>(ios.pword(ix: get_id())); }
30
31 static Property& create(std::ios_base& ios)
32 {
33 BOOST_ASSERT_MSG(!get_impl(ios), "Called create while the property already exists");
34 const int id = get_id();
35 ios.register_callback(fn: callback, index: id);
36 Property* value = new Property();
37 ios.pword(ix: id) = value;
38 return *value;
39 }
40
41 static void callback(std::ios_base::event ev, std::ios_base& ios, int id)
42 {
43 Property* prop = get_impl(ios);
44 if(!prop)
45 return;
46 switch(ev) {
47 case std::ios_base::erase_event:
48 delete prop;
49 ios.pword(ix: id) = nullptr;
50 break;
51 case std::ios_base::copyfmt_event: ios.pword(ix: id) = new Property(*prop); break;
52 case std::ios_base::imbue_event: prop->on_imbue(); break;
53 default: break;
54 }
55 }
56 static int get_id()
57 {
58 static int id = std::ios_base::xalloc();
59 return id;
60 }
61 };
62
63}}} // namespace boost::locale::impl
64
65#endif
66

source code of boost/libs/locale/src/boost/locale/shared/ios_prop.hpp