summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/endian/test/endian_arithmetic_test.cpp
blob: 725aac2a5887f663f617b12a144f0865b1825d07 (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
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright 2019 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

#include <boost/endian/arithmetic.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <cstddef>

template<BOOST_SCOPED_ENUM(boost::endian::order) Order, BOOST_SCOPED_ENUM(boost::endian::align) Align, class T> void test_arithmetic_( T const& x )
{
    boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x );

    BOOST_TEST_EQ( +x, +y );

    BOOST_TEST_EQ( x + x, y + y );
    BOOST_TEST_EQ( x - x, y - y );

    BOOST_TEST_EQ( x * x, y * y );
    BOOST_TEST_EQ( x / x, y / y );

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 += x, y2 += y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 -= x, y2 -= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 *= x, y2 *= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 /= x, y2 /= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( ++x2, ++y2 );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( --x2, --y2 );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2++, y2++ );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2--, y2-- );
    }
}

template<BOOST_SCOPED_ENUM(boost::endian::order) Order, BOOST_SCOPED_ENUM(boost::endian::align) Align, class T> void test_integral_( T const& x )
{
    boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y( x );

    BOOST_TEST_EQ( x % x, y % y );

    BOOST_TEST_EQ( x & x, y & y );
    BOOST_TEST_EQ( x | x, y | y );
    BOOST_TEST_EQ( x ^ x, y ^ y );

    BOOST_TEST_EQ( x << 1, y << 1 );
    BOOST_TEST_EQ( x >> 1, y >> 1 );

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 %= x, y2 %= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 &= x, y2 &= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 |= x, y2 |= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 ^= x, y2 ^= y );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 <<= 1, y2 <<= 1 );
    }

    {
        T x2( x );
        boost::endian::endian_arithmetic<Order, T, sizeof(T) * 8, Align> y2( y );

        BOOST_TEST_EQ( x2 >>= 1, y2 >>= 1 );
    }
}

template<class T> void test_arithmetic( T const& x )
{
    test_arithmetic_<boost::endian::order::little, boost::endian::align::no>( x );
    test_arithmetic_<boost::endian::order::little, boost::endian::align::yes>( x );
    test_arithmetic_<boost::endian::order::big, boost::endian::align::no>( x );
    test_arithmetic_<boost::endian::order::big, boost::endian::align::yes>( x );
}

template<class T> void test_integral( T const& x )
{
    test_arithmetic( x );

    test_integral_<boost::endian::order::little, boost::endian::align::no>( x );
    test_integral_<boost::endian::order::little, boost::endian::align::yes>( x );
    test_integral_<boost::endian::order::big, boost::endian::align::no>( x );
    test_integral_<boost::endian::order::big, boost::endian::align::yes>( x );
}

int main()
{
    test_integral( 0x7EF2 );
    test_integral( 0x01020304u );

    test_arithmetic( 3.1416f );
    test_arithmetic( 3.14159 );

    return boost::report_errors();
}