// Unit test for boost::lexical_cast. // // See http://www.boost.org for most recent version, including documentation. // // Copyright Antony Polukhin, 2011-2019. // // 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 #include #include #include ///////////////////////// char streamable classes /////////////////////////////////////////// struct streamable_easy { enum ENU {value = 0}; }; std::ostream& operator << (std::ostream& ostr, const streamable_easy&) { return ostr << streamable_easy::value; } std::istream& operator >> (std::istream& istr, const streamable_easy&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_easy::value); return istr; } struct streamable_medium { enum ENU {value = 1}; }; template typename boost::enable_if, std::basic_ostream&>::type operator << (std::basic_ostream& ostr, const streamable_medium&) { return ostr << streamable_medium::value; } template typename boost::enable_if, std::basic_istream&>::type operator >> (std::basic_istream& istr, const streamable_medium&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_medium::value); return istr; } struct streamable_hard { enum ENU {value = 2}; }; template typename boost::enable_if, std::basic_ostream&>::type operator << (std::basic_ostream& ostr, const streamable_hard&) { return ostr << streamable_hard::value; } template typename boost::enable_if, std::basic_istream&>::type operator >> (std::basic_istream& istr, const streamable_hard&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard::value); return istr; } struct streamable_hard2 { enum ENU {value = 3}; }; template std::basic_ostream& operator << (std::basic_ostream& ostr, const streamable_hard2&) { return ostr << streamable_hard2::value; } template std::basic_istream& operator >> (std::basic_istream& istr, const streamable_hard2&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard2::value); return istr; } ///////////////////////// wchar_t streamable classes /////////////////////////////////////////// struct wstreamable_easy { enum ENU {value = 4}; }; std::wostream& operator << (std::wostream& ostr, const wstreamable_easy&) { return ostr << wstreamable_easy::value; } std::wistream& operator >> (std::wistream& istr, const wstreamable_easy&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_easy::value); return istr; } struct wstreamable_medium { enum ENU {value = 5}; }; template typename boost::enable_if, std::basic_ostream& >::type operator << (std::basic_ostream& ostr, const wstreamable_medium&) { return ostr << wstreamable_medium::value; } template typename boost::enable_if, std::basic_istream& >::type operator >> (std::basic_istream& istr, const wstreamable_medium&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_medium::value); return istr; } struct wstreamable_hard { enum ENU {value = 6}; }; template typename boost::enable_if, std::basic_ostream&>::type operator << (std::basic_ostream& ostr, const wstreamable_hard&) { return ostr << wstreamable_hard::value; } template typename boost::enable_if, std::basic_istream&>::type operator >> (std::basic_istream& istr, const wstreamable_hard&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard::value); return istr; } struct wstreamable_hard2 { enum ENU {value = 7}; }; template std::basic_ostream& operator << (std::basic_ostream& ostr, const wstreamable_hard2&) { return ostr << wstreamable_hard2::value; } template std::basic_istream& operator >> (std::basic_istream& istr, const wstreamable_hard2&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard2::value); return istr; } ///////////////////////// char and wchar_t streamable classes /////////////////////////////////////////// struct bistreamable_easy { enum ENU {value = 8}; }; std::ostream& operator << (std::ostream& ostr, const bistreamable_easy&) { return ostr << bistreamable_easy::value; } std::istream& operator >> (std::istream& istr, const bistreamable_easy&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value); return istr; } std::wostream& operator << (std::wostream& ostr, const bistreamable_easy&) { return ostr << bistreamable_easy::value + 100; } std::wistream& operator >> (std::wistream& istr, const bistreamable_easy&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value + 100); return istr; } struct bistreamable_medium { enum ENU {value = 9}; }; template std::basic_ostream& operator << (std::basic_ostream& ostr, const bistreamable_medium&) { return ostr << bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100); } template std::basic_istream& operator >> (std::basic_istream& istr, const bistreamable_medium&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100)); return istr; } struct bistreamable_hard { enum ENU {value = 10}; }; template std::basic_ostream& operator << (std::basic_ostream& ostr, const bistreamable_hard&) { return ostr << bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100); } template std::basic_istream& operator >> (std::basic_istream& istr, const bistreamable_hard&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100)); return istr; } struct bistreamable_hard2 { enum ENU {value = 11}; }; template std::basic_ostream& operator << (std::basic_ostream& ostr, const bistreamable_hard2&) { return ostr << bistreamable_hard2::value; } template std::basic_istream& operator >> (std::basic_istream& istr, const bistreamable_hard2&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value); return istr; } template std::basic_ostream& operator << (std::basic_ostream& ostr, const bistreamable_hard2&) { return ostr << bistreamable_hard2::value + 100; } template std::basic_istream& operator >> (std::basic_istream& istr, const bistreamable_hard2&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value + 100); return istr; } void test_ostream_character_detection(); void test_istream_character_detection(); void test_mixed_stream_character_detection(); boost::unit_test::test_suite *init_unit_test_suite(int, char *[]) { boost::unit_test::test_suite *suite = BOOST_TEST_SUITE("lexical_cast stream character detection"); suite->add(BOOST_TEST_CASE(&test_ostream_character_detection)); suite->add(BOOST_TEST_CASE(&test_istream_character_detection)); suite->add(BOOST_TEST_CASE(&test_mixed_stream_character_detection)); return suite; } template static void test_ostr_impl() { T streamable; BOOST_CHECK_EQUAL(T::value, boost::lexical_cast(streamable)); BOOST_CHECK_EQUAL(boost::lexical_cast(T::value), boost::lexical_cast(streamable)); } template static void test_wostr_impl() { T streamable; BOOST_CHECK_EQUAL(T::value, boost::lexical_cast(streamable)); // BOOST_CHECK_EQUAL(boost::lexical_cast(T::value), boost::lexical_cast(streamable)); // Shall not compile??? BOOST_CHECK(boost::lexical_cast(T::value) == boost::lexical_cast(streamable)); } template static void test_bistr_impl() { T streamable; BOOST_CHECK_EQUAL(T::value, boost::lexical_cast(streamable)); BOOST_CHECK_EQUAL(boost::lexical_cast(T::value), boost::lexical_cast(streamable)); BOOST_CHECK(boost::lexical_cast(T::value + 100) == boost::lexical_cast(streamable)); } void test_ostream_character_detection() { test_ostr_impl(); test_ostr_impl(); test_ostr_impl(); test_ostr_impl(); test_wostr_impl(); test_wostr_impl(); test_wostr_impl(); test_wostr_impl(); test_bistr_impl(); test_bistr_impl(); test_bistr_impl(); test_bistr_impl(); } template static void test_istr_impl() { boost::lexical_cast(T::value); boost::lexical_cast(boost::lexical_cast(T::value)); } template static void test_wistr_impl() { boost::lexical_cast(T::value); //boost::lexical_cast(boost::lexical_cast(T::value)); // Shall not compile??? boost::lexical_cast(boost::lexical_cast(T::value)); } template static void test_bistr_instr_impl() { boost::lexical_cast(T::value); boost::lexical_cast(boost::lexical_cast(T::value)); boost::lexical_cast(boost::lexical_cast(T::value + 100)); } void test_istream_character_detection() { test_istr_impl(); test_istr_impl(); test_istr_impl(); test_istr_impl(); test_wistr_impl(); test_wistr_impl(); test_wistr_impl(); test_wistr_impl(); test_bistr_instr_impl(); test_bistr_instr_impl(); test_bistr_instr_impl(); test_bistr_instr_impl(); } struct wistreamble_ostreamable { enum ENU {value = 200}; }; std::ostream& operator << (std::ostream& ostr, const wistreamble_ostreamable&) { return ostr << wistreamble_ostreamable::value; } std::wistream& operator >> (std::wistream& istr, const wistreamble_ostreamable&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, wistreamble_ostreamable::value); return istr; } struct istreamble_wostreamable { enum ENU {value = 201}; }; std::wostream& operator << (std::wostream& ostr, const istreamble_wostreamable&) { return ostr << istreamble_wostreamable::value; } std::istream& operator >> (std::istream& istr, const istreamble_wostreamable&) { int i; istr >> i; BOOST_CHECK_EQUAL(i, istreamble_wostreamable::value); return istr; } void test_mixed_stream_character_detection() { //boost::lexical_cast(std::string("qwe")); // TODO: ALLOW IT AS EXTENSION! boost::lexical_cast(wistreamble_ostreamable::value); BOOST_CHECK_EQUAL(boost::lexical_cast(wistreamble_ostreamable()), wistreamble_ostreamable::value); boost::lexical_cast(istreamble_wostreamable::value); BOOST_CHECK_EQUAL(boost::lexical_cast(istreamble_wostreamable()), istreamble_wostreamable::value); }