You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jk...@apache.org on 2017/02/18 19:32:06 UTC

thrift git commit: THRIFT-3921: Add ostream operator<< functions for enums (working with THRIFT-4060) Client: C++

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