Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / archive / iterators / transform_width.hpp
1 #ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
2 #define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP
3
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
6 # pragma once
7 #endif
8
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
10 // transform_width.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 // 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
26
27 #include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
28 #include <boost/pfto.hpp>
29
30 #include <boost/iterator/iterator_adaptor.hpp>
31 #include <boost/iterator/iterator_traits.hpp>
32
33 namespace boost { 
34 namespace archive {
35 namespace iterators {
36
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
45 >
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
53     >
54 {
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;
63
64     typedef transform_width<Base, BitsOut, BitsIn, CharType> this_t;
65     typedef BOOST_DEDUCED_TYPENAME iterator_value<Base>::type base_value_type;
66
67     CharType fill();
68
69     CharType dereference_impl(){
70         if(! m_full){
71             m_current_value = fill();
72             m_full = true;
73         }
74         return m_current_value;
75     }
76
77     CharType dereference() const {
78         return const_cast<this_t *>(this)->dereference_impl();
79     }
80
81     // test for iterator equality
82     bool equal(const this_t & rhs) const {
83         return
84             this->base_reference() == rhs.base_reference();
85         ;
86     }
87
88     void increment(){
89         m_displacement += BitsOut;
90
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());
98             }
99         }
100         m_full = false;
101     }
102
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;
111
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)
120     {}
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)
129     {}
130 };
131
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;
142         }
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;
160     }
161     return retval;
162 }
163
164 } // namespace iterators
165 } // namespace archive
166 } // namespace boost
167
168 #endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP