source: NonGTP/Boost/boost/iostreams/detail/codecvt_helper.hpp @ 857

Revision 857, 8.1 KB checked in by igarcia, 19 years ago (diff)
Line 
1// (C) Copyright Jonathan Turkanis 2003.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5// See http://www.boost.org/libs/iostreams for documentation.
6
7// Contains the definition of the template codecvt_helper, useful for
8// defining specializations of std::codecvt where state_type != mbstate_t.
9// Compensates for the fact that some standard library implementations
10// do not derive the primiary codecvt template from locale::facet or
11// provide the correct member types and functions.
12
13// Usage:
14//
15// // In global namespace:
16// BOOST_IOSTREAMS_CODECVT_SPEC(mystate)
17//
18// // In user namespace:
19// template<typename Intern, typename Extern>
20// struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... };
21//
22// // Or:
23// struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... };
24//
25// Etc.
26
27#ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
28#define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
29
30#if defined(_MSC_VER) && (_MSC_VER >= 1020)
31# pragma once
32#endif
33
34#include <boost/config.hpp>  // Put size_t in std, BOOST_MSVC, Dinkum.
35#include <boost/detail/workaround.hpp>
36#include <algorithm>         // min.
37#include <cstddef>           // size_t.
38#include <locale>            // locale, codecvt_base, codecvt.
39#include <boost/iostreams/detail/config/codecvt.hpp>
40
41//------------------Definition of traits--------------------------------------//
42
43namespace boost { namespace iostreams { namespace detail {
44
45#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------//
46
47template<typename T>
48struct codecvt_intern { typedef typename T::intern_type type; };
49
50template<typename T>
51struct codecvt_extern { typedef typename T::extern_type type; };
52
53#else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------//
54
55template<typename T>
56struct codecvt_intern { typedef typename T::from_type type; };
57
58template<typename T>
59struct codecvt_extern { typedef typename T::to_type type; };
60
61#endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------//
62
63template<typename T>
64struct codecvt_state { typedef typename T::state_type type; };
65
66} } } // End namespaces detail, iostreams, boost.
67
68//------------------Definition of codecvt_impl--------------------------------//
69
70#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
71    defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \
72    defined(BOOST_IOSTREAMS_NO_LOCALE) \
73    /**/
74
75namespace boost { namespace iostreams { namespace detail {
76
77template<typename Intern, typename Extern, typename State>
78struct codecvt_impl : std::locale::facet, std::codecvt_base {
79public:
80    typedef Intern  intern_type;
81    typedef Extern  extern_type;
82    typedef State   state_type;
83
84    codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { }
85
86    std::codecvt_base::result
87    in( State& state, const Extern* first1, const Extern* last1,
88        const Extern*& next1, Intern* first2, Intern* last2,
89        Intern*& next2 ) const
90    {
91        return do_in(state, first1, last1, next1, first2, last2, next2);
92    }
93
94    std::codecvt_base::result
95    out( State& state, const Intern* first1, const Intern* last1,
96         const Intern*& next1, Extern* first2, Extern* last2,
97         Extern*& next2 ) const
98    {
99        return do_out(state, first1, last1, next1, first2, last2, next2);
100    }
101
102    std::codecvt_base::result
103    unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const
104    {
105        return do_unshift(state, first2, last2, next2);
106    }
107
108    bool always_noconv() const throw() { return do_always_noconv(); }
109
110    int max_length() const throw() { return do_max_length(); }
111
112    int encoding() const throw() { return do_encoding(); }
113
114    int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state,
115                const Extern* first1, const Extern* last1,
116                std::size_t len2 ) const throw()
117    {
118        return do_length(state, first1, last1, len2);
119    }
120protected:
121    std::codecvt_base::result
122    virtual do_in( State&, const Extern*, const Extern*, const Extern*&,
123                   Intern*, Intern*, Intern*& ) const
124    {
125        return std::codecvt_base::noconv;
126    }
127
128    std::codecvt_base::result
129    virtual do_out( State&, const Intern*, const Intern*, const Intern*&,
130                    Extern*, Extern*, Extern*& ) const
131    {
132        return std::codecvt_base::noconv;
133    }
134
135    std::codecvt_base::result
136    virtual do_unshift( State& state, Extern* first2, Extern* last2,
137                        Extern*& next2 ) const
138    {
139        return std::codecvt_base::ok;
140    }
141
142    virtual bool do_always_noconv() const throw() { return true; }
143
144    virtual int do_max_length() const throw() { return 1; }
145
146    virtual int do_encoding() const throw() { return 1; }
147
148    virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state,
149                           const Extern* first1, const Extern* last1,
150                           std::size_t len2 ) const throw()
151    {
152        return (std::min)(static_cast<std::size_t>(last1 - first1), len2);
153    }
154};
155
156} } } // End namespaces detail, iostreams, boost.
157
158#endif // no primary codecvt definition, empty definition.
159
160//------------------Definition of BOOST_IOSTREAMS_CODECVT_SPEC----------------//
161
162#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
163    defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \
164    /**/
165# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
166#  define BOOST_IOSTREAMS_CODECVT_SPEC(state) \
167    namespace std { \
168        template<typename Intern, typename Extern> \
169        class codecvt<Intern, Extern, state> \
170            : public ::boost::iostreams::detail::codecvt_impl< \
171                         Intern, Extern, state \
172                     > \
173        { \
174        public: \
175            codecvt(std::size_t refs = 0) \
176                : ::boost::iostreams::detail::codecvt_impl< \
177                      Intern, Extern, state \
178                  >(refs) \
179                { } \
180            static std::locale::id id; \
181        }; \
182        template<typename Intern, typename Extern> \
183        std::locale::id codecvt<Intern, Extern, state>::id; \
184    } \
185    /**/
186# else
187#  define BOOST_IOSTREAMS_CODECVT_SPEC(state) \
188    namespace std { \
189        template<> \
190        class codecvt<wchar_t, char, state> \
191            : public ::boost::iostreams::detail::codecvt_impl< \
192                         wchar_t, char, state \
193                     > \
194        { \
195        public: \
196            codecvt(std::size_t refs = 0) \
197                : ::boost::iostreams::detail::codecvt_impl< \
198                      wchar_t, char, state \
199                  >(refs) \
200                { } \
201            static std::locale::id id; \
202        }; \
203        template<> \
204        std::locale::id codecvt<wchar_t, char, state>::id; \
205    } \
206    /**/
207# endif
208#else
209# define BOOST_IOSTREAMS_CODECVT_SPEC(state)
210#endif // no primary codecvt definition, or empty definition.
211
212namespace boost { namespace iostreams { namespace detail {
213                   
214//------------------Definition of codecvt_helper------------------------------//
215
216template<typename Intern, typename Extern, typename State>
217struct codecvt_helper : std::codecvt<Intern, Extern, State> {
218    typedef Intern  intern_type;
219    typedef Extern  extern_type;
220    typedef State   state_type;
221    codecvt_helper(std::size_t refs = 0)
222    #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T)
223        : std::codecvt<Intern, Extern, State>(refs)
224    #else
225        : std::codecvt<Intern, Extern, State>()
226    #endif
227        { }
228#ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH
229    int max_length() const throw() { return do_max_length(); }
230protected:
231    virtual int do_max_length() const throw() { return 1; }
232#endif
233};
234
235} } } // End namespaces detail, iostreams, boost.
236
237#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.