~ubuntu-branches/ubuntu/trusty/liblas/trusty-proposed

« back to all changes in this revision

Viewing changes to include/liblas/external/property_tree/stream_translator.hpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-01-05 17:00:29 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140105170029-ddtp0j63x5jvck2u
Tags: 1.7.0+dfsg-2
Fixed missing linking of system boost component.
(closes: #733282)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ----------------------------------------------------------------------------
 
2
// Copyright (C) 2009 Sebastian Redl
 
3
//
 
4
// Distributed under the Boost Software License, Version 1.0. 
 
5
// (See accompanying file LICENSE_1_0.txt or copy at 
 
6
// http://www.boost.org/LICENSE_1_0.txt)
 
7
//
 
8
// For more information, see www.boost.org
 
9
// ----------------------------------------------------------------------------
 
10
 
 
11
#ifndef LIBLAS_BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
 
12
#define LIBLAS_BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
 
13
 
 
14
#include <liblas/external/property_tree/ptree_fwd.hpp>
 
15
 
 
16
#include <boost/optional.hpp>
 
17
#include <boost/optional/optional_io.hpp>
 
18
#include <boost/utility/enable_if.hpp>
 
19
#include <boost/type_traits/decay.hpp>
 
20
#include <boost/type_traits/integral_constant.hpp>
 
21
#include <sstream>
 
22
#include <string>
 
23
#include <locale>
 
24
#include <limits>
 
25
 
 
26
namespace liblas { namespace property_tree
 
27
{
 
28
 
 
29
    template <typename Ch, typename Traits, typename E, typename Enabler = void>
 
30
    struct customize_stream
 
31
    {
 
32
        static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
 
33
            s << e;
 
34
        }
 
35
        static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
 
36
            s >> e;
 
37
            if(!s.eof()) {
 
38
                s >> std::ws;
 
39
            }
 
40
        }
 
41
    };
 
42
 
 
43
    // No whitespace skipping for single characters.
 
44
    template <typename Ch, typename Traits>
 
45
    struct customize_stream<Ch, Traits, Ch, void>
 
46
    {
 
47
        static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
 
48
            s << e;
 
49
        }
 
50
        static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
 
51
            s.unsetf(std::ios_base::skipws);
 
52
            s >> e;
 
53
        }
 
54
    };
 
55
 
 
56
    // Ugly workaround for numeric_traits that don't have members when not
 
57
    // specialized, e.g. MSVC.
 
58
    namespace detail
 
59
    {
 
60
        template <bool is_specialized>
 
61
        struct is_inexact_impl
 
62
        {
 
63
            template <typename T>
 
64
            struct test
 
65
            {
 
66
                typedef boost::false_type type;
 
67
            };
 
68
        };
 
69
        template <>
 
70
        struct is_inexact_impl<true>
 
71
        {
 
72
            template <typename T>
 
73
            struct test
 
74
            {
 
75
              typedef boost::integral_constant<bool,
 
76
                  !std::numeric_limits<T>::is_exact> type;
 
77
            };
 
78
        };
 
79
 
 
80
        template <typename F>
 
81
        struct is_inexact
 
82
        {
 
83
            typedef typename boost::decay<F>::type decayed;
 
84
            typedef typename is_inexact_impl<
 
85
                std::numeric_limits<decayed>::is_specialized
 
86
            >::BOOST_NESTED_TEMPLATE test<decayed>::type type;
 
87
            static const bool value = type::value;
 
88
        };
 
89
    }
 
90
 
 
91
    template <typename Ch, typename Traits, typename F>
 
92
    struct customize_stream<Ch, Traits, F,
 
93
        typename boost::enable_if< detail::is_inexact<F> >::type
 
94
    >
 
95
    {
 
96
        static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
 
97
            s.precision(std::numeric_limits<F>::digits10 + 1);
 
98
            s << e;
 
99
        }
 
100
        static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
 
101
            s >> e;
 
102
            if(!s.eof()) {
 
103
                s >> std::ws;
 
104
            }
 
105
        }
 
106
    };
 
107
 
 
108
    template <typename Ch, typename Traits>
 
109
    struct customize_stream<Ch, Traits, bool, void>
 
110
    {
 
111
        static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
 
112
            s.setf(std::ios_base::boolalpha);
 
113
            s << e;
 
114
        }
 
115
        static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
 
116
            s >> e;
 
117
            if(s.fail()) {
 
118
                // Try again in word form.
 
119
                s.clear();
 
120
                s.setf(std::ios_base::boolalpha);
 
121
                s >> e;
 
122
            }
 
123
            if(!s.eof()) {
 
124
                s >> std::ws;
 
125
            }
 
126
        }
 
127
    };
 
128
 
 
129
    template <typename Ch, typename Traits>
 
130
    struct customize_stream<Ch, Traits, signed char, void>
 
131
    {
 
132
        static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
 
133
            s << (int)e;
 
134
        }
 
135
        static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
 
136
            int i;
 
137
            s >> i;
 
138
            // out of range?
 
139
            if(i > (std::numeric_limits<signed char>::max)() ||
 
140
                i < (std::numeric_limits<signed char>::min)())
 
141
            {
 
142
                s.clear(); // guarantees eof to be unset
 
143
                return;
 
144
            }
 
145
            e = (signed char)i;
 
146
            if(!s.eof()) {
 
147
                s >> std::ws;
 
148
            }
 
149
        }
 
150
    };
 
151
 
 
152
    template <typename Ch, typename Traits>
 
153
    struct customize_stream<Ch, Traits, unsigned char, void>
 
154
    {
 
155
        static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
 
156
            s << (unsigned)e;
 
157
        }
 
158
        static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
 
159
            unsigned i;
 
160
            s >> i;
 
161
            // out of range?
 
162
            if(i > (std::numeric_limits<unsigned char>::max)()) {
 
163
                s.clear(); // guarantees eof to be unset
 
164
                return;
 
165
            }
 
166
            e = (unsigned char)i;
 
167
            if(!s.eof()) {
 
168
                s >> std::ws;
 
169
            }
 
170
        }
 
171
    };
 
172
 
 
173
    /// Implementation of Translator that uses the stream overloads.
 
174
    template <typename Ch, typename Traits, typename Alloc, typename E>
 
175
    class stream_translator
 
176
    {
 
177
        typedef customize_stream<Ch, Traits, E> customized;
 
178
    public:
 
179
        typedef std::basic_string<Ch, Traits, Alloc> internal_type;
 
180
        typedef E external_type;
 
181
 
 
182
        explicit stream_translator(std::locale loc = std::locale())
 
183
            : m_loc(loc)
 
184
        {}
 
185
 
 
186
        boost::optional<E> get_value(const internal_type &v) {
 
187
            std::basic_istringstream<Ch, Traits, Alloc> iss(v);
 
188
            iss.imbue(m_loc);
 
189
            E e;
 
190
            customized::extract(iss, e);
 
191
            if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
 
192
                return boost::optional<E>();
 
193
            }
 
194
            return e;
 
195
        }
 
196
        boost::optional<internal_type> put_value(const E &v) {
 
197
            std::basic_ostringstream<Ch, Traits, Alloc> oss;
 
198
            oss.imbue(m_loc);
 
199
            customized::insert(oss, v);
 
200
            if(oss) {
 
201
                return oss.str();
 
202
            }
 
203
            return boost::optional<internal_type>();
 
204
        }
 
205
 
 
206
    private:
 
207
        std::locale m_loc;
 
208
    };
 
209
 
 
210
    // This is the default translator when basic_string is the internal type.
 
211
    // Unless the external type is also basic_string, in which case
 
212
    // id_translator takes over.
 
213
    template <typename Ch, typename Traits, typename Alloc, typename E>
 
214
    struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
 
215
    {
 
216
        typedef stream_translator<Ch, Traits, Alloc, E> type;
 
217
    };
 
218
 
 
219
}}
 
220
 
 
221
#endif