Release 1.39.0
[boost.git] / Boost_1_39_0 / boost / archive / iterators / transform_width.hpp
blobc2e9bee12e3a6fcfcbcc8df227a3792f756cc307
1 #ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
2 #define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6 # pragma once
7 #endif
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // transform_width.hpp
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)
17 // See http://www.boost.org for updates, documentation, and revision history.
19 // iterator which takes elements of x bits and returns elements of y bits.
20 // used to change streams of 8 bit characters into streams of 6 bit characters.
21 // and vice-versa for implementing base64 encodeing/decoding. Be very careful
22 // when using and end iterator. end is only reliable detected when the input
23 // stream length is some common multiple of x and y. E.G. Base64 6 bit
24 // character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
25 // or 3 8 bit characters
27 #include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
28 #include <boost/serialization/pfto.hpp>
30 #include <boost/iterator/iterator_adaptor.hpp>
31 #include <boost/iterator/iterator_traits.hpp>
33 namespace boost {
34 namespace archive {
35 namespace iterators {
37 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
38 // class used by text archives to translate char strings to wchar_t
39 // strings of the currently selected locale
40 template<
41 class Base,
42 int BitsOut,
43 int BitsIn,
44 class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type // output character
46 class transform_width :
47 public boost::iterator_adaptor<
48 transform_width<Base, BitsOut, BitsIn, CharType>,
49 Base,
50 CharType,
51 single_pass_traversal_tag,
52 CharType
55 friend class boost::iterator_core_access;
56 typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
57 transform_width<Base, BitsOut, BitsIn, CharType>,
58 Base,
59 CharType,
60 single_pass_traversal_tag,
61 CharType
62 > super_t;
64 typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
65 typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;
67 CharType fill();
69 CharType dereference_impl(){
70 if(! m_full){
71 m_current_value = fill();
72 m_full = true;
74 return m_current_value;
77 CharType dereference() const {
78 return const_cast<this_t *>(this)->dereference_impl();
81 // test for iterator equality
82 bool equal(const this_t & rhs) const {
83 return
84 this->base_reference() == rhs.base_reference();
88 void increment(){
89 m_displacement += BitsOut;
91 while(m_displacement >= BitsIn){
92 m_displacement -= BitsIn;
93 if(0 == m_displacement)
94 m_bufferfull = false;
95 if(! m_bufferfull){
96 // note: suspect that this is not invoked for borland
97 ++(this->base_reference());
100 m_full = false;
103 CharType m_current_value;
104 // number of bits left in current input character buffer
105 unsigned int m_displacement;
106 base_value_type m_buffer;
107 // flag to current output character is ready - just used to save time
108 bool m_full;
109 // flag to indicate that m_buffer has data
110 bool m_bufferfull;
112 public:
113 // make composible buy using templated constructor
114 template<class T>
115 transform_width(BOOST_PFTO_WRAPPER(T) start) :
116 super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast<T>(start)))),
117 m_displacement(0),
118 m_full(false),
119 m_bufferfull(false)
121 // intel 7.1 doesn't like default copy constructor
122 transform_width(const transform_width & rhs) :
123 super_t(rhs.base_reference()),
124 m_current_value(rhs.m_current_value),
125 m_displacement(rhs.m_displacement),
126 m_buffer(rhs.m_buffer),
127 m_full(rhs.m_full),
128 m_bufferfull(rhs.m_bufferfull)
132 template<class Base, int BitsOut, int BitsIn, class CharType>
133 CharType transform_width<Base, BitsOut, BitsIn, CharType>::fill(){
134 CharType retval = 0;
135 unsigned int missing_bits = BitsOut;
136 for(;;){
137 unsigned int bcount;
138 if(! m_bufferfull){
139 m_buffer = * this->base_reference();
140 m_bufferfull = true;
141 bcount = BitsIn;
143 else
144 bcount = BitsIn - m_displacement;
145 unsigned int i = (std::min)(bcount, missing_bits);
146 // shift interesting bits to least significant position
147 unsigned int j = m_buffer >> (bcount - i);
148 // strip off uninteresting bits
149 // (note presumption of two's complement arithmetic)
150 j &= ~(-(1 << i));
151 // append then interesting bits to the output value
152 retval <<= i;
153 retval |= j;
154 missing_bits -= i;
155 if(0 == missing_bits)
156 break;
157 // note: suspect that this is not invoked for borland 5.51
158 ++(this->base_reference());
159 m_bufferfull = false;
161 return retval;
164 } // namespace iterators
165 } // namespace archive
166 } // namespace boost
168 #endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP