File: unformatted_ostream_iterator.cpp

package info (click to toggle)
range-v3 0.12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,652 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 19; perl: 15
file content (114 lines) | stat: -rw-r--r-- 3,935 bytes parent folder | download | duplicates (3)
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
// Range v3 library
//
//  Copyright Eric Niebler 2014-present
//  Copyright Google LLC 2020-present
//
//  Use, modification and distribution is subject to 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)
//
// Project home: https://github.com/ericniebler/range-v3
#include <sstream>
#include <string>
#include <vector>

#include <range/v3/algorithm/copy.hpp>
#include <range/v3/iterator/stream_iterators.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/view/reverse.hpp>
#include <range/v3/view/sliding.hpp>
#include <range/v3/view/stride.hpp>

#include "../simple_test.hpp"
#include "../test_utils.hpp"

namespace
{
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    template<typename>
    std::string endian_adjust(std::string const & s)
    {
        return s;
    }
#else
    template<typename T>
    std::string endian_adjust(std::string const & s)
    {
        namespace rv = ranges::views;
        return rv::sliding(s, static_cast<std::ptrdiff_t>(sizeof(T))) //
               | rv::stride(static_cast<std::ptrdiff_t>(sizeof(T)))   //
               | rv::for_each([](auto x) { return x | rv::reverse; }) //
               | ranges::to<std::string>;
    }
#endif // endianness
} // namespace

int main()
{
    {
        constexpr auto expected = "\x21\x22\x23\x24";

        {
            auto const input = std::vector<char>{0x21, 0x22, 0x23, 0x24};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = output.str();
            CHECK(actual == expected);
        }
        {
            auto const input = std::vector<unsigned short>{0x2122, 0x2324};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = endian_adjust<unsigned short>(output.str());
            CHECK(actual == expected);
        }
#if __cplusplus > 201703L
        {
            // float computed to be *exactly* 0x21222324.
            auto const input = std::vector<float>{0x1.4446480000000000179Dp-61f};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = endian_adjust<float>(output.str());
            CHECK(actual == expected);
        }
#endif // __cplusplus > 201703L
    }
    {
        constexpr auto expected = "\x21\x22\x23\x24\x25\x26\x27\x28";
        {
            auto const input = std::vector<unsigned int>{0x21222324, 0x25262728};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = endian_adjust<unsigned int>(output.str());
            CHECK(actual == expected);
        }
#if __cplusplus > 201703L
        {
            // floats computed to be *exactly* 0x21222324 and 0x25262728.
            auto const input =
                std::vector<float>{0x1.4446480000000000179Dp-61f, 0x1.4C4E5p-53f};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = endian_adjust<unsigned int>(output.str());
            CHECK(actual == expected);
        }
        {
            // double computed to be *exactly* 0x2122232425262728.
            auto const input = std::vector<double>{0x1.223242526272800006F2p-493};
            auto output = std::ostringstream();
            ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));

            auto const actual = endian_adjust<double>(output.str());
            CHECK(actual == expected);
        }
#endif // __cplusplus > 201703L
    }
    return ::test_result();
}