blob: 4b1a1c401138defea8f809994ee5bbd86d8c72cc [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// (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 the definition of the template codecvt_helper, useful for
9// defining specializations of std::codecvt where state_type != mbstate_t.
10// Compensates for the fact that some standard library implementations
11// do not derive the primiary codecvt template from locale::facet or
12// provide the correct member types and functions.
13
14// Usage:
15//
16// // In global namespace:
17// NDNBOOST_IOSTREAMS_CODECVT_SPEC(mystate)
18//
19// // In user namespace:
20// template<typename Intern, typename Extern>
21// struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... };
22//
23// // Or:
24// struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... };
25//
26// Etc.
27
28#ifndef NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
29#define NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
30
31#if defined(_MSC_VER) && (_MSC_VER >= 1020)
32# pragma once
33#endif
34
35#include <ndnboost/config.hpp> // Put size_t in std, NDNBOOST_MSVC, Dinkum.
36#include <ndnboost/detail/workaround.hpp>
37#include <algorithm> // min.
38#include <cstddef> // size_t.
39#include <locale> // locale, codecvt_base, codecvt.
40#include <ndnboost/iostreams/detail/config/codecvt.hpp>
41
42//------------------Definition of traits--------------------------------------//
43
44namespace ndnboost { namespace iostreams { namespace detail {
45
46#if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //-----------------------//
47
48template<typename T>
49struct codecvt_intern { typedef typename T::intern_type type; };
50
51template<typename T>
52struct codecvt_extern { typedef typename T::extern_type type; };
53
54#else // #if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //--------------//
55
56template<typename T>
57struct codecvt_intern { typedef typename T::from_type type; };
58
59template<typename T>
60struct codecvt_extern { typedef typename T::to_type type; };
61
62#endif // #if !NDNBOOST_WORKAROUND(NDNBOOST_DINKUMWARE_STDLIB, == 1) //-------------//
63
64template<typename T>
65struct codecvt_state { typedef typename T::state_type type; };
66
67} } } // End namespaces detail, iostreams, boost.
68
69//------------------Definition of codecvt_impl--------------------------------//
70
71#if defined(NDNBOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
72 defined(NDNBOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \
73 defined(NDNBOOST_IOSTREAMS_NO_LOCALE) \
74 /**/
75
76namespace ndnboost { namespace iostreams { namespace detail {
77
78template<typename Intern, typename Extern, typename State>
79struct codecvt_impl : std::locale::facet, std::codecvt_base {
80public:
81 typedef Intern intern_type;
82 typedef Extern extern_type;
83 typedef State state_type;
84
85 codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { }
86
87 std::codecvt_base::result
88 in( State& state, const Extern* first1, const Extern* last1,
89 const Extern*& next1, Intern* first2, Intern* last2,
90 Intern*& next2 ) const
91 {
92 return do_in(state, first1, last1, next1, first2, last2, next2);
93 }
94
95 std::codecvt_base::result
96 out( State& state, const Intern* first1, const Intern* last1,
97 const Intern*& next1, Extern* first2, Extern* last2,
98 Extern*& next2 ) const
99 {
100 return do_out(state, first1, last1, next1, first2, last2, next2);
101 }
102
103 std::codecvt_base::result
104 unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const
105 {
106 return do_unshift(state, first2, last2, next2);
107 }
108
109 bool always_noconv() const throw() { return do_always_noconv(); }
110
111 int max_length() const throw() { return do_max_length(); }
112
113 int encoding() const throw() { return do_encoding(); }
114
115 int length( NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state,
116 const Extern* first1, const Extern* last1,
117 std::size_t len2 ) const throw()
118 {
119 return do_length(state, first1, last1, len2);
120 }
121protected:
122 std::codecvt_base::result
123 virtual do_in( State&, const Extern*, const Extern*, const Extern*&,
124 Intern*, Intern*, Intern*& ) const
125 {
126 return std::codecvt_base::noconv;
127 }
128
129 std::codecvt_base::result
130 virtual do_out( State&, const Intern*, const Intern*, const Intern*&,
131 Extern*, Extern*, Extern*& ) const
132 {
133 return std::codecvt_base::noconv;
134 }
135
136 std::codecvt_base::result
137 virtual do_unshift(State&, Extern*, Extern*, Extern*&) 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( NDNBOOST_IOSTREAMS_CODECVT_CV_QUALIFIER 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 NDNBOOST_IOSTREAMS_CODECVT_SPEC----------------//
161
162#if defined(NDNBOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
163 defined(NDNBOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \
164 /**/
165# ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
166# define NDNBOOST_IOSTREAMS_CODECVT_SPEC(state) \
167 namespace std { \
168 template<typename Intern, typename Extern> \
169 class codecvt<Intern, Extern, state> \
170 : public ::ndnboost::iostreams::detail::codecvt_impl< \
171 Intern, Extern, state \
172 > \
173 { \
174 public: \
175 codecvt(std::size_t refs = 0) \
176 : ::ndnboost::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 NDNBOOST_IOSTREAMS_CODECVT_SPEC(state) \
188 namespace std { \
189 template<> \
190 class codecvt<wchar_t, char, state> \
191 : public ::ndnboost::iostreams::detail::codecvt_impl< \
192 wchar_t, char, state \
193 > \
194 { \
195 public: \
196 codecvt(std::size_t refs = 0) \
197 : ::ndnboost::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 NDNBOOST_IOSTREAMS_CODECVT_SPEC(state)
210#endif // no primary codecvt definition, or empty definition.
211
212namespace ndnboost { 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(NDNBOOST_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 NDNBOOST_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 NDNBOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED