Repository: thrift Updated Branches: refs/heads/master 400b346db -> 655b9b6ef
THRIFT-3921: Add ostream operator<< functions for enums (working with THRIFT-4060) Client: C++ This closes #1083 This closes #1194 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/655b9b6e Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/655b9b6e Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/655b9b6e Branch: refs/heads/master Commit: 655b9b6ef86c45b423a194abee2a9cd057a16a74 Parents: 400b346 Author: Vivek Jain <vi...@vivekja.in> Authored: Wed Sep 7 10:34:25 2016 -0700 Committer: James E. King, III <jk...@apache.org> Committed: Sat Feb 18 14:30:46 2017 -0500 ---------------------------------------------------------------------- .../cpp/src/thrift/generate/t_cpp_generator.cc | 42 ++++++++++++++++++++ lib/cpp/test/EnumTest.cpp | 35 +++++++++++++++- test/EnumTest.thrift | 5 +++ 3 files changed, 80 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/655b9b6e/compiler/cpp/src/thrift/generate/t_cpp_generator.cc ---------------------------------------------------------------------- diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc index 1c82e09..869d802 100644 --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc @@ -107,6 +107,7 @@ public: void generate_typedef(t_typedef* ttypedef); void generate_enum(t_enum* tenum); + void generate_enum_ostream_operator(t_enum* tenum); void generate_forward_declaration(t_struct* tstruct); void generate_struct(t_struct* tstruct) { generate_cpp_struct(tstruct, false); } void generate_xception(t_struct* txception) { generate_cpp_struct(txception, true); } @@ -566,6 +567,47 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { << tenum->get_name() << "Values" << ", _k" << tenum->get_name() << "Names), " << "::apache::thrift::TEnumIterator(-1, NULL, NULL));" << endl << endl; + + generate_enum_ostream_operator(tenum); +} + +void t_cpp_generator::generate_enum_ostream_operator(t_enum* tenum) { + + // If we've been told the consuming application will provide an ostream + // operator definition then we only make a declaration: + + if (!has_custom_ostream(tenum)) { + f_types_ << "inline "; + } + + f_types_ << "std::ostream& operator<<(std::ostream& out, const "; + if (gen_pure_enums_) { + f_types_ << tenum->get_name(); + } else { + f_types_ << tenum->get_name() << "::type&"; + } + f_types_ << " val)"; + if (has_custom_ostream(tenum)) { + f_types_ << ";"; + } else { + scope_up(f_types_); + + f_types_ << indent() << "std::map<int, const char*>::const_iterator it = _" + << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl; + f_types_ << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << endl; + indent_up(); + f_types_ << indent() << "out << it->second;" << endl; + indent_down(); + f_types_ << indent() << "} else {" << endl; + indent_up(); + f_types_ << indent() << "out << static_cast<int>(val);" << endl; + indent_down(); + f_types_ << indent() << "}" << endl; + + f_types_ << indent() << "return out;" << endl; + scope_down(f_types_); + } + f_types_ << endl; } /** http://git-wip-us.apache.org/repos/asf/thrift/blob/655b9b6e/lib/cpp/test/EnumTest.cpp ---------------------------------------------------------------------- diff --git a/lib/cpp/test/EnumTest.cpp b/lib/cpp/test/EnumTest.cpp index 0e34b16..c935bc4 100644 --- a/lib/cpp/test/EnumTest.cpp +++ b/lib/cpp/test/EnumTest.cpp @@ -20,9 +20,15 @@ #include <boost/test/unit_test.hpp> #include "gen-cpp/EnumTest_types.h" +std::ostream& operator <<(std::ostream& os, const MyEnumWithCustomOstream::type& val) +{ + os << "{" << (int)val << ":CUSTOM!" << "}"; + return os; +} + BOOST_AUTO_TEST_SUITE(EnumTest) -BOOST_AUTO_TEST_CASE(test_enum) { +BOOST_AUTO_TEST_CASE(test_enum_value) { // Check that all the enum values match what we expect BOOST_CHECK_EQUAL(MyEnum1::ME1_0, 0); BOOST_CHECK_EQUAL(MyEnum1::ME1_1, 1); @@ -47,9 +53,34 @@ BOOST_AUTO_TEST_CASE(test_enum) { BOOST_CHECK_EQUAL(MyEnum4::ME4_A, 0x7ffffffd); BOOST_CHECK_EQUAL(MyEnum4::ME4_B, 0x7ffffffe); BOOST_CHECK_EQUAL(MyEnum4::ME4_C, 0x7fffffff); + + BOOST_CHECK_EQUAL(MyEnum5::e1, 0); + BOOST_CHECK_EQUAL(MyEnum5::e2, 42); +} + +template <class _T> +std::string EnumToString(_T e) +{ + std::stringstream ss; + ss << e; + return ss.str(); +} + + +BOOST_AUTO_TEST_CASE(test_enum_ostream) +{ + BOOST_CHECK_EQUAL(EnumToString(MyEnum1::ME1_0), "ME1_0"); + BOOST_CHECK_EQUAL(EnumToString(MyEnum5::e2), "e2"); + BOOST_CHECK_EQUAL(EnumToString(MyEnum3::ME3_N1), "ME3_N1"); + BOOST_CHECK_EQUAL(EnumToString(MyEnumWithCustomOstream::CustoM2), "{2:CUSTOM!}"); + + // some invalid or unknown value + MyEnum5::type uut = (MyEnum5::type)44; + BOOST_CHECK_EQUAL(EnumToString(uut), "44"); } -BOOST_AUTO_TEST_CASE(test_enum_constant) { +BOOST_AUTO_TEST_CASE(test_enum_constant) +{ MyStruct ms; BOOST_CHECK_EQUAL(ms.me2_2, 2); BOOST_CHECK_EQUAL(ms.me3_n2, -2); http://git-wip-us.apache.org/repos/asf/thrift/blob/655b9b6e/test/EnumTest.thrift ---------------------------------------------------------------------- diff --git a/test/EnumTest.thrift b/test/EnumTest.thrift index f38cec3..7961f38 100644 --- a/test/EnumTest.thrift +++ b/test/EnumTest.thrift @@ -71,6 +71,11 @@ enum MyEnum5 { e2 = 42 // fails with 0.9.3 and earlier } +enum MyEnumWithCustomOstream { + custom1 = 1, + CustoM2 +} (cpp.customostream) + struct MyStruct { 1: MyEnum2 me2_2 = MyEnum1.ME2_2 2: MyEnum3 me3_n2 = MyEnum3.ME3_N2