1#ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
2#define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
3
4// MS compatible compilers support #pragma once
5#if defined(_MSC_VER)
6# pragma once
7#endif
8
9/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10// mb_from_wchar.hpp
11
12// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
13// Use, modification and distribution is subject to the Boost Software
14// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16
17// See http://www.boost.org for updates, documentation, and revision history.
18
19#include <boost/assert.hpp>
20#include <cstddef> // size_t
21#include <cstring> // memcpy
22#ifndef BOOST_NO_CWCHAR
23#include <cwchar> // mbstate_t
24#endif
25#include <boost/config.hpp>
26#if defined(BOOST_NO_STDC_NAMESPACE)
27namespace std{
28 using ::mbstate_t;
29 using ::memcpy;
30} // namespace std
31#endif
32
33#include <boost/archive/detail/utf8_codecvt_facet.hpp>
34#include <boost/iterator/iterator_adaptor.hpp>
35
36namespace boost {
37namespace archive {
38namespace iterators {
39
40/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
41// class used by text archives to translate wide strings and to char
42// strings of the currently selected locale
43template<class Base> // the input iterator
44class mb_from_wchar
45 : public boost::iterator_adaptor<
46 mb_from_wchar<Base>,
47 Base,
48 wchar_t,
49 single_pass_traversal_tag,
50 char
51 >
52{
53 friend class boost::iterator_core_access;
54
55 typedef typename boost::iterator_adaptor<
56 mb_from_wchar<Base>,
57 Base,
58 wchar_t,
59 single_pass_traversal_tag,
60 char
61 > super_t;
62
63 typedef mb_from_wchar<Base> this_t;
64
65 char dereference_impl() {
66 if(! m_full){
67 fill();
68 m_full = true;
69 }
70 return m_buffer[m_bnext];
71 }
72
73 char dereference() const {
74 return (const_cast<this_t *>(this))->dereference_impl();
75 }
76 // test for iterator equality
77 bool equal(const mb_from_wchar<Base> & rhs) const {
78 // once the value is filled, the base_reference has been incremented
79 // so don't permit comparison anymore.
80 return
81 0 == m_bend
82 && 0 == m_bnext
83 && this->base_reference() == rhs.base_reference()
84 ;
85 }
86
87 void fill(){
88 wchar_t value = * this->base_reference();
89 const wchar_t *wend;
90 char *bend;
91 BOOST_VERIFY(
92 m_codecvt_facet.out(
93 m_mbs,
94 & value, & value + 1, wend,
95 m_buffer, m_buffer + sizeof(m_buffer), bend
96 )
97 ==
98 std::codecvt_base::ok
99 );
100 m_bnext = 0;
101 m_bend = bend - m_buffer;
102 }
103
104 void increment(){
105 if(++m_bnext < m_bend)
106 return;
107 m_bend =
108 m_bnext = 0;
109 ++(this->base_reference());
110 m_full = false;
111 }
112
113 boost::archive::detail::utf8_codecvt_facet m_codecvt_facet;
114 std::mbstate_t m_mbs;
115 // buffer to handle pending characters
116 char m_buffer[9 /* MB_CUR_MAX */];
117 std::size_t m_bend;
118 std::size_t m_bnext;
119 bool m_full;
120
121public:
122 // make composable by using templated constructor
123 template<class T>
124 mb_from_wchar(T start) :
125 super_t(Base(static_cast< T >(start))),
126 m_mbs(std::mbstate_t()),
127 m_bend(0),
128 m_bnext(0),
129 m_full(false)
130 {}
131 // intel 7.1 doesn't like default copy constructor
132 mb_from_wchar(const mb_from_wchar & rhs) :
133 super_t(rhs.base_reference()),
134 m_mbs(rhs.m_mbs),
135 m_bend(rhs.m_bend),
136 m_bnext(rhs.m_bnext),
137 m_full(rhs.m_full)
138 {
139 std::memcpy(dest: m_buffer, src: rhs.m_buffer, n: sizeof(m_buffer));
140 }
141};
142
143} // namespace iterators
144} // namespace archive
145} // namespace boost
146
147#endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
148

source code of boost/libs/serialization/include/boost/archive/iterators/mb_from_wchar.hpp