// endian_operations_test.cpp --------------------------------------------------------// // Copyright Beman Dawes 2008 // 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) // See library home page at http://www.boost.org/libs/endian //--------------------------------------------------------------------------------------// // This test probes operator overloading, including interaction between // operand types. // See endian_test for tests of endianness correctness, size, and value. #include #ifdef _MSC_VER # pragma warning( disable : 4242 ) // conversion ..., possible loss of data # pragma warning( disable : 4244 ) // conversion ..., possible loss of data # pragma warning( disable : 4018 ) // signed/unsigned mismatch # pragma warning( disable : 4365 ) // signed/unsigned mismatch # pragma warning( disable : 4389 ) // signed/unsigned mismatch #elif defined(__GNUC__) # pragma GCC diagnostic ignored "-Wconversion" #endif #include #include #include #include #include #include #include #include namespace be = boost::endian; template struct value_type { typedef typename T::value_type type; }; template<> struct value_type { typedef char type; }; template<> struct value_type { typedef unsigned char type; }; template<> struct value_type { typedef signed char type; }; template<> struct value_type { typedef short type; }; template<> struct value_type { typedef unsigned short type; }; template<> struct value_type { typedef int type; }; template<> struct value_type { typedef unsigned int type; }; template<> struct value_type { typedef long type; }; template<> struct value_type { typedef unsigned long type; }; template<> struct value_type { typedef long long type; }; template<> struct value_type { typedef unsigned long long type; }; template struct default_construct { static void test() { T1 o1; o1 = 1; // quiet warnings if (o1) return; // quiet warnings } }; template struct construct { static void test() { T2 o2(1); T1 o1(static_cast(o2)); ++o1; // quiet gcc unused variable warning } }; template struct initialize { static void test() { T1 o2(2); T1 o1 = o2; ++o1; // quiet gcc unused variable warning } }; template struct assign { static void test() { T2 o2; o2 = 1; T1 o1; o1 = o2; if (o1) return; // quiet warnings } }; template struct do_relational { static void test() { T1 o1(1); T2 o2(2); BOOST_TEST( !(o1 == o2) ); BOOST_TEST( o1 != o2 ); BOOST_TEST( o1 < o2 ); BOOST_TEST( o1 <= o2 ); BOOST_TEST( !(o1 > o2) ); BOOST_TEST( !(o1 >= o2 ) ); } }; template struct do_relational { static void test() { } }; template struct relational { static void test() { do_relational::type>::value == boost::is_signed::type>::value >::test(); // do_relational::test(); } }; template struct op_plus { static void test() { T1 o1(1); T2 o2(2); T1 o3; o3 = +o1; o3 = o1 + o2; o1 += o2; if (o3) return; // quiet warnings } }; template struct op_star { static void test() { T1 o1(1); T2 o2(2); T1 o3; o3 = o1 * o2; o1 *= o2; if (o3) return; // quiet warnings } }; template class Test, class T1> void op_test_aux() { Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); #ifdef BOOST_LONG_ENDIAN_TEST Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); Test::test(); #endif } template class Test> void op_test() { op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); #ifdef BOOST_LONG_ENDIAN_TEST op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); op_test_aux(); #endif } // test_inserter_and_extractor -----------------------------------------------------// void test_inserter_and_extractor() { std::cout << "test inserter and extractor..." << std::endl; be::big_uint64_t bu64(0x010203040506070ULL); be::little_uint64_t lu64(0x010203040506070ULL); boost::uint64_t x; std::stringstream ss; ss << bu64; ss >> x; BOOST_TEST_EQ(x, 0x010203040506070ULL); ss.clear(); ss << lu64; ss >> x; BOOST_TEST_EQ(x, 0x010203040506070ULL); ss.clear(); ss << 0x010203040506070ULL; be::big_uint64_t bu64z(0); ss >> bu64z; BOOST_TEST_EQ(bu64z, bu64); ss.clear(); ss << 0x010203040506070ULL; be::little_uint64_t lu64z(0); ss >> lu64z; BOOST_TEST_EQ(lu64z, lu64); std::cout << "test inserter and extractor complete" << std::endl; } void f_big_int32_ut(be::big_int32_t) {} // main ------------------------------------------------------------------------------// int cpp_main(int, char * []) { // make sure some simple things work be::big_int32_t o1(1); be::big_int32_t o2(2L); be::big_int32_t o3(3LL); be::big_int64_t o4(1); std::clog << "set up test values\n"; be::big_int32_t big(12345); be::little_uint16_t little_u(10); be::big_int64_t result; // this is the use case that is so irritating that it caused the endian // constructors to be made non-explicit std::clog << "\nf(1234) where f(big_int32_t)\n"; f_big_int32_ut(1234); std::clog << "\nresult = big\n"; result = big; std::clog << "\nresult = +big\n"; result = +big; std::clog << "\nresult = -big\n"; result = -big; std::clog << "\n++big\n"; ++big; std::clog << "\nresult = big++\n"; result = big++; std::clog << "\n--big\n"; --big; std::clog << "\nbig--\n"; big--; std::clog << "\nresult = big * big\n"; result = big * big; std::clog << "\nresult = big * big\n"; result = big * big; std::clog << "\nresult = big * little_u\n"; result = big * little_u; std::clog << "\nbig *= little_u\n"; big *= little_u; std::clog << "\nresult = little_u * big\n"; result = little_u * big; std::clog << "\nresult = big * 5\n"; result = big * 5; std::clog << "\nbig *= 5\n"; big *= 5; std::clog << "\nresult = 5 * big\n"; result = 5 * big; std::clog << "\nresult = little_u * 5\n"; result = little_u * 5; std::clog << "\nresult = 5 * little_u\n"; result = 5 * little_u; std::clog << "\nresult = 5 * 10\n"; result = 5 * 10; std::clog << "\n"; // test from Roland Schwarz that detected ambiguities; these ambiguities // were eliminated by BOOST_ENDIAN_MINIMAL_COVER_OPERATORS unsigned u; be::little_uint32_t u1; be::little_uint32_t u2; u = 9; u1 = 1; std::clog << "\nu2 = u1 + u\n"; u2 = u1 + u; std::clog << "\n"; // variations to detect ambiguities be::little_uint32_t u3 = u1 + 5; u3 = u1 + 5u; if (u1 == 5) {} if (u1 == 5u) {} u1 += 5; u1 += 5u; u2 = u1 + 5; u2 = u1 + 5u; // one more wrinkle be::little_uint16_t u4(3); u4 = 3; std::clog << "\nu2 = u1 + u4\n"; u2 = u1 + u4; std::clog << "\n"; test_inserter_and_extractor(); // perform the indicated test on ~60*60 operand types op_test(); op_test(); // includes copy construction op_test(); op_test(); op_test(); op_test(); op_test(); return boost::report_errors(); }