1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2003-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5 
6 // See http://www.boost.org/libs/iostreams for documentation.
7 
8 // Contains machinery for performing code conversion.
9 
10 #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
11 #define BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
12 
13 #if defined(_MSC_VER)
14 # pragma once
15 #endif
16 
17 #include <cwchar>            // mbstate_t.
18 #include <locale>            // codecvt, locale.
19 #include <boost/config.hpp>  // HAS_MACRO_USE_FACET.
20 #include <boost/iostreams/detail/config/codecvt.hpp>
21 
22 namespace boost { namespace iostreams { namespace detail {
23 
24 struct default_codecvt {
25     typedef wchar_t         intern_type, from_type;
26     typedef char            extern_type, to_type;
27     typedef std::mbstate_t  state_type;
28 };
29 
30 template<typename Codecvt>
31 struct codecvt_holder {
32     typedef Codecvt codecvt_type;
getboost::iostreams::detail::codecvt_holder33     const codecvt_type& get() const { return codecvt_; }
imbueboost::iostreams::detail::codecvt_holder34     void imbue(const std::locale&) { }
35     Codecvt codecvt_;
36 };
37 
38 template<>
39 struct codecvt_holder<default_codecvt> {
40     typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
codecvt_holderboost::iostreams::detail::codecvt_holder41     codecvt_holder() { reset_codecvt(); }
getboost::iostreams::detail::codecvt_holder42     const codecvt_type& get() const { return *codecvt_; }
imbueboost::iostreams::detail::codecvt_holder43     void imbue(const std::locale& loc)
44     {
45         loc_ = loc;
46         reset_codecvt();
47     }
reset_codecvtboost::iostreams::detail::codecvt_holder48     void reset_codecvt()
49     {
50         using namespace std;
51         #ifndef BOOST_HAS_MACRO_USE_FACET
52             codecvt_ = & use_facet< codecvt_type >(loc_);
53         #else
54             codecvt_ = & _USE(loc_, codecvt_type);
55         #endif
56     }
57     std::locale loc_; // Prevent codecvt_ from being freed.
58     const codecvt_type* codecvt_;
59 };
60 
61 } } } // End namespaces detail, iostreams, boost.
62 
63 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED
64