summaryrefslogtreecommitdiff
path: root/libs/conversion/test/lexical_cast_empty_input_test.cpp
blob: 5a5881bcbf78ec9b8eed938c2643c527ec997b59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//  Unit test for boost::lexical_cast.
//
//  See http://www.boost.org for most recent version, including documentation.
//
//  Copyright Antony Polukhin, 2011.
//
//  Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).

#include <boost/config.hpp>

#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif

#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator_range.hpp>

using namespace boost;

#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif

template <class T>
void do_test_on_empty_input(T& v)
{
    BOOST_CHECK_THROW(lexical_cast<int>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<float>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<double>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<long double>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned int>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned short>(v), bad_lexical_cast);
#if defined(BOOST_HAS_LONG_LONG)
    BOOST_CHECK_THROW(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
#elif defined(BOOST_HAS_MS_INT64)
    BOOST_CHECK_THROW(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<__int64>(v), bad_lexical_cast);
#endif
}

void test_empty_iterator_range()
{

    boost::iterator_range<char*> v;
    do_test_on_empty_input(v);
    BOOST_CHECK_EQUAL(lexical_cast<std::string>(v), std::string());
    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);

    boost::iterator_range<const char*> cv;
    do_test_on_empty_input(cv);
    BOOST_CHECK_EQUAL(lexical_cast<std::string>(cv), std::string());
    BOOST_CHECK_THROW(lexical_cast<char>(cv), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(cv), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(cv), bad_lexical_cast);

    const boost::iterator_range<const char*> ccv;
    do_test_on_empty_input(ccv);
    BOOST_CHECK_EQUAL(lexical_cast<std::string>(ccv), std::string());
    BOOST_CHECK_THROW(lexical_cast<char>(ccv), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(ccv), bad_lexical_cast);
}

void test_empty_string()
{
    std::string v;
    do_test_on_empty_input(v);
    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);

#ifndef BOOST_LCAST_NO_WCHAR_T
    std::wstring vw;
    do_test_on_empty_input(vw);
    BOOST_CHECK_THROW(lexical_cast<wchar_t>(vw), bad_lexical_cast);
#endif

// Currently, no compiler and STL library fully support char16_t and char32_t
//#ifndef BOOST_NO_CHAR16_T
//    std::basic_string<char16_t> v16w;
//    do_test_on_empty_input(v16w);
//    BOOST_CHECK_THROW(lexical_cast<char16_t>(v16w), bad_lexical_cast);
//#endif
//#ifndef BOOST_NO_CHAR32_T
//    std::basic_string<char32_t> v32w;
//    do_test_on_empty_input(v32w);
//    BOOST_CHECK_THROW(lexical_cast<char32_t>(v32w), bad_lexical_cast);
//#endif
}

struct Escape
{
    Escape(const std::string& s)
        : str_(s)
    {}

    std::string str_;
};

inline std::ostream& operator<< (std::ostream& o, const Escape& rhs)
{
    return o << rhs.str_;
}

void test_empty_user_class()
{
    Escape v("");
    do_test_on_empty_input(v);
    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}

namespace std {
inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
{
    std::ostream_iterator<long> it(out);
    std::copy(v.begin(), v.end(), it);
    assert(out);
    return out;
}
}

void test_empty_vector()
{
    std::vector<long> v;
    do_test_on_empty_input(v);
    BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
    BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}

unit_test::test_suite *init_unit_test_suite(int, char *[])
{
    unit_test::test_suite *suite =
        BOOST_TEST_SUITE("lexical_cast. Empty input unit test");
    suite->add(BOOST_TEST_CASE(&test_empty_iterator_range));
    suite->add(BOOST_TEST_CASE(&test_empty_string));
    suite->add(BOOST_TEST_CASE(&test_empty_user_class));
    suite->add(BOOST_TEST_CASE(&test_empty_vector));

    return suite;
}