1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 // Copyright 2018-2020 Mateusz Loskot <mateusz at loskot dot net>
4 //
5 // Distributed under the Boost Software License, Version 1.0
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 //
9 #include <boost/gil/channel_algorithm.hpp>
10
11 #include <boost/core/lightweight_test.hpp>
12
13 #include <type_traits>
14 #include <utility>
15
16 #include "test_fixture.hpp"
17 #include "test_utility_output_stream.hpp"
18
19 namespace gil = boost::gil;
20 namespace fixture = boost::gil::test::fixture;
21
22 template <typename ChannelFixtureBase>
test_channel_arithmetic_mutable(std::false_type)23 void test_channel_arithmetic_mutable(std::false_type) {}
24
25 template <typename ChannelFixtureBase>
test_channel_arithmetic_mutable(std::true_type)26 void test_channel_arithmetic_mutable(std::true_type)
27 {
28 using fixture_t = fixture::channel<ChannelFixtureBase>;
29 using channel_value_t = typename fixture_t::channel_value_t;
30 fixture_t f;
31 channel_value_t const v = f.min_v_;
32 channel_value_t const one = 1;
33
34 ++f.min_v_;
35 f.min_v_++;
36 --f.min_v_;
37 f.min_v_--;
38 BOOST_TEST_EQ(v, f.min_v_);
39
40 f.min_v_ += one;
41 f.min_v_ -= one;
42 BOOST_TEST_EQ(v, f.min_v_);
43
44 f.min_v_ *= one;
45 f.min_v_ /= one;
46 BOOST_TEST_EQ(v, f.min_v_);
47
48 f.min_v_ = one; // assignable to scalar
49 BOOST_TEST_EQ(f.min_v_, one);
50 f.min_v_ = v; // and to value type
51 BOOST_TEST_EQ(f.min_v_, v);
52
53 // test swap
54 channel_value_t v1 = f.min_v_;
55 channel_value_t v2 = f.max_v_;
56 std::swap(f.min_v_, f.max_v_);
57 BOOST_TEST_GT(f.min_v_, f.max_v_);
58 channel_value_t v3 = f.min_v_;
59 channel_value_t v4 = f.max_v_;
60 BOOST_TEST_EQ(v1, v4);
61 BOOST_TEST_EQ(v2, v3);
62 }
63
64 template <typename ChannelFixtureBase>
test_channel_arithmetic()65 void test_channel_arithmetic()
66 {
67 using fixture_t = fixture::channel<ChannelFixtureBase>;
68 fixture_t f;
69 BOOST_TEST_EQ(f.min_v_ * 1, f.min_v_);
70 BOOST_TEST_EQ(f.min_v_ / 1, f.min_v_);
71 BOOST_TEST_EQ((f.min_v_ + 1) + 1, f.min_v_ + 2);
72 BOOST_TEST_EQ((f.max_v_ - 1) - 1, f.max_v_ - 2);
73
74 using is_mutable_t = std::integral_constant
75 <
76 bool,
77 gil::channel_traits<typename fixture_t::channel_t>::is_mutable
78 >;
79 test_channel_arithmetic_mutable<ChannelFixtureBase>(is_mutable_t{});
80 }
81
82 struct test_channel_value
83 {
84 template <typename Channel>
operator ()test_channel_value85 void operator()(Channel const &)
86 {
87 using channel_t = Channel;
88 using fixture_t = fixture::channel_value<channel_t>;
89 test_channel_arithmetic<fixture_t>();
90 }
runtest_channel_value91 static void run()
92 {
93 boost::mp11::mp_for_each<fixture::channel_byte_types>(test_channel_value{});
94 }
95 };
96
97 struct test_channel_reference
98 {
99 template <typename Channel>
operator ()test_channel_reference100 void operator()(Channel const &)
101 {
102 using channel_t = Channel;
103 using fixture_t = fixture::channel_reference<channel_t &>;
104 test_channel_arithmetic<fixture_t>();
105 }
runtest_channel_reference106 static void run()
107 {
108 boost::mp11::mp_for_each<fixture::channel_byte_types>(test_channel_reference{});
109 }
110 };
111
112 struct test_channel_reference_const
113 {
114 template <typename Channel>
operator ()test_channel_reference_const115 void operator()(Channel const &)
116 {
117 using channel_t = Channel;
118 using fixture_t = fixture::channel_reference<channel_t const &>;
119 test_channel_arithmetic<fixture_t>();
120 }
runtest_channel_reference_const121 static void run()
122 {
123 boost::mp11::mp_for_each<fixture::channel_byte_types>(test_channel_reference_const{});
124 }
125 };
126
127 struct test_packed_channel_reference
128 {
129 template <typename BitField>
operator ()test_packed_channel_reference130 void operator()(BitField const &)
131 {
132 using bitfield_t = BitField;
133 using channels565_t = fixture::packed_channels565<bitfield_t>;
134 test_channel_arithmetic<typename channels565_t::fixture_0_5_t>();
135 test_channel_arithmetic<typename channels565_t::fixture_5_6_t>();
136 test_channel_arithmetic<typename channels565_t::fixture_11_5_t>();
137 }
runtest_packed_channel_reference138 static void run()
139 {
140 boost::mp11::mp_for_each<fixture::channel_bitfield_types>(test_packed_channel_reference{});
141 }
142 };
143
144 struct test_packed_dynamic_channel_reference
145 {
146
147 template <typename BitField>
operator ()test_packed_dynamic_channel_reference148 void operator()(BitField const &)
149 {
150 using bitfield_t = BitField;
151 using channels565_t = fixture::packed_dynamic_channels565<bitfield_t>;
152 test_channel_arithmetic<typename channels565_t::fixture_5_t>();
153 test_channel_arithmetic<typename channels565_t::fixture_6_t>();
154 }
runtest_packed_dynamic_channel_reference155 static void run()
156 {
157 boost::mp11::mp_for_each<fixture::channel_bitfield_types>(test_packed_dynamic_channel_reference{});
158 }
159 };
160
main()161 int main()
162 {
163 test_channel_value::run();
164 test_channel_reference::run();
165 test_channel_reference_const::run();
166 test_packed_channel_reference::run();
167 test_packed_dynamic_channel_reference::run();
168
169 return ::boost::report_errors();
170 }
171