summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKonrad Grochowski <hcorg@minions.org.pl>2014-09-02 16:00:47 +0200
committerRoger Meier <roger@apache.org>2014-09-03 23:41:32 +0200
commitb3f6ea100fae38a568e1844923c4c945cab5b536 (patch)
tree92acbdf1ffda626fdd60510ab1c8d10fea5e0575 /lib
parentd0bd17e7263cb8f92c21d3e1dad2ee5b5e9f79e5 (diff)
downloadthrift-b3f6ea100fae38a568e1844923c4c945cab5b536.tar.gz
THRIFT-2067 C++: all generated objects provide ostream operator<<
Diffstat (limited to 'lib')
-rwxr-xr-xlib/cpp/Makefile.am3
-rw-r--r--lib/cpp/src/thrift/TToString.h89
-rwxr-xr-xlib/cpp/test/Makefile.am3
-rw-r--r--lib/cpp/test/ToStringTest.cpp137
4 files changed, 230 insertions, 2 deletions
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index ab9108a48..4bd40fbe2 100755
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -131,7 +131,8 @@ include_thrift_HEADERS = \
src/thrift/TProcessor.h \
src/thrift/TApplicationException.h \
src/thrift/TLogging.h \
- src/thrift/cxxfunctional.h
+ src/thrift/cxxfunctional.h \
+ src/thrift/TToString.h
include_concurrencydir = $(include_thriftdir)/concurrency
include_concurrency_HEADERS = \
diff --git a/lib/cpp/src/thrift/TToString.h b/lib/cpp/src/thrift/TToString.h
new file mode 100644
index 000000000..c160e09df
--- /dev/null
+++ b/lib/cpp/src/thrift/TToString.h
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TOSTRING_H_
+#define _THRIFT_TOSTRING_H_ 1
+
+#include <boost/lexical_cast.hpp>
+
+#include <vector>
+#include <map>
+#include <set>
+#include <string>
+#include <sstream>
+
+namespace apache { namespace thrift {
+
+template <typename T>
+std::string to_string(const T& t) {
+ return boost::lexical_cast<std::string>(t);
+}
+
+template <typename K, typename V>
+std::string to_string(const std::map<K, V>& m);
+
+template <typename T>
+std::string to_string(const std::set<T>& s);
+
+template <typename T>
+std::string to_string(const std::vector<T>& t);
+
+template <typename K, typename V>
+std::string to_string(const typename std::pair<K, V>& v) {
+ std::ostringstream o;
+ o << to_string(v.first) << ": " << to_string(v.second);
+ return o.str();
+}
+
+template <typename T>
+std::string to_string(const T& beg, const T& end)
+{
+ std::ostringstream o;
+ for (T it = beg; it != end; ++it) {
+ if (it != beg)
+ o << ", ";
+ o << to_string(*it);
+ }
+ return o.str();
+}
+
+template <typename T>
+std::string to_string(const std::vector<T>& t) {
+ std::ostringstream o;
+ o << "[" << to_string(t.begin(), t.end()) << "]";
+ return o.str();
+}
+
+template <typename K, typename V>
+std::string to_string(const std::map<K, V>& m) {
+ std::ostringstream o;
+ o << "{" << to_string(m.begin(), m.end()) << "}";
+ return o.str();
+}
+
+template <typename T>
+std::string to_string(const std::set<T>& s) {
+ std::ostringstream o;
+ o << "{" << to_string(s.begin(), s.end()) << "}";
+ return o.str();
+}
+
+}} // apache::thrift
+
+#endif // _THRIFT_TOSTRING_H_
diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am
index 6779ac655..c1fad3e3e 100755
--- a/lib/cpp/test/Makefile.am
+++ b/lib/cpp/test/Makefile.am
@@ -82,7 +82,8 @@ UnitTests_SOURCES = \
UnitTestMain.cpp \
TMemoryBufferTest.cpp \
TBufferBaseTest.cpp \
- Base64Test.cpp
+ Base64Test.cpp \
+ ToStringTest.cpp
if !WITH_BOOSTTHREADS
UnitTests_SOURCES += \
diff --git a/lib/cpp/test/ToStringTest.cpp b/lib/cpp/test/ToStringTest.cpp
new file mode 100644
index 000000000..1a89c11e9
--- /dev/null
+++ b/lib/cpp/test/ToStringTest.cpp
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <vector>
+#include <map>
+
+#include <boost/test/auto_unit_test.hpp>
+
+#include <thrift/TToString.h>
+
+#include "gen-cpp/ThriftTest_types.h"
+#include "gen-cpp/OptionalRequiredTest_types.h"
+#include "gen-cpp/DebugProtoTest_types.h"
+
+using apache::thrift::to_string;
+
+BOOST_AUTO_TEST_SUITE( ToStringTest )
+
+BOOST_AUTO_TEST_CASE( base_types_to_string ) {
+ BOOST_CHECK_EQUAL(to_string(10), "10");
+ BOOST_CHECK_EQUAL(to_string(true), "1");
+ BOOST_CHECK_EQUAL(to_string('a'), "a");
+ BOOST_CHECK_EQUAL(to_string(1.2), "1.2");
+ BOOST_CHECK_EQUAL(to_string("abc"), "abc");
+}
+
+BOOST_AUTO_TEST_CASE( empty_vector_to_string ) {
+ std::vector<int> l;
+ BOOST_CHECK_EQUAL(to_string(l), "[]");
+}
+
+BOOST_AUTO_TEST_CASE( single_item_vector_to_string ) {
+ std::vector<int> l;
+ l.push_back(100);
+ BOOST_CHECK_EQUAL(to_string(l), "[100]");
+}
+
+BOOST_AUTO_TEST_CASE( multiple_item_vector_to_string ) {
+ std::vector<int> l;
+ l.push_back(100);
+ l.push_back(150);
+ BOOST_CHECK_EQUAL(to_string(l), "[100, 150]");
+}
+
+BOOST_AUTO_TEST_CASE( empty_map_to_string ) {
+ std::map<int, std::string> m;
+ BOOST_CHECK_EQUAL(to_string(m), "{}");
+}
+
+BOOST_AUTO_TEST_CASE( single_item_map_to_string ) {
+ std::map<int, std::string> m;
+ m[12] = "abc";
+ BOOST_CHECK_EQUAL(to_string(m), "{12: abc}");
+}
+
+BOOST_AUTO_TEST_CASE( multi_item_map_to_string ) {
+ std::map<int, std::string> m;
+ m[12] = "abc";
+ m[31] = "xyz";
+ BOOST_CHECK_EQUAL(to_string(m), "{12: abc, 31: xyz}");
+}
+
+BOOST_AUTO_TEST_CASE( empty_set_to_string ) {
+ std::set<char> s;
+ BOOST_CHECK_EQUAL(to_string(s), "{}");
+}
+
+BOOST_AUTO_TEST_CASE( single_item_set_to_string ) {
+ std::set<char> s;
+ s.insert('c');
+ BOOST_CHECK_EQUAL(to_string(s), "{c}");
+}
+
+BOOST_AUTO_TEST_CASE( multi_item_set_to_string ) {
+ std::set<char> s;
+ s.insert('a');
+ s.insert('z');
+ BOOST_CHECK_EQUAL(to_string(s), "{a, z}");
+}
+
+BOOST_AUTO_TEST_CASE( generated_empty_object_to_string ) {
+ thrift::test::EmptyStruct e;
+ BOOST_CHECK_EQUAL(to_string(e), "EmptyStruct()");
+}
+
+BOOST_AUTO_TEST_CASE( generated_single_basic_field_object_to_string ) {
+ thrift::test::StructA a;
+ a.__set_s("abcd");
+ BOOST_CHECK_EQUAL(to_string(a), "StructA(s=abcd)");
+}
+
+BOOST_AUTO_TEST_CASE( generated_two_basic_fields_object_to_string ) {
+ thrift::test::Bonk a;
+ a.__set_message("abcd");
+ a.__set_type(1234);
+ BOOST_CHECK_EQUAL(to_string(a), "Bonk(message=abcd, type=1234)");
+}
+
+BOOST_AUTO_TEST_CASE( generated_optional_fields_object_to_string ) {
+ thrift::test::Tricky2 a;
+ BOOST_CHECK_EQUAL(to_string(a), "Tricky2(im_optional=<null>)");
+ a.__set_im_optional(123);
+ BOOST_CHECK_EQUAL(to_string(a), "Tricky2(im_optional=123)");
+}
+
+BOOST_AUTO_TEST_CASE( generated_nested_object_to_string ) {
+ thrift::test::OneField a;
+ BOOST_CHECK_EQUAL(to_string(a), "OneField(field=EmptyStruct())");
+}
+
+BOOST_AUTO_TEST_CASE( generated_nested_list_object_to_string ) {
+ thrift::test::ListBonks l;
+ l.bonk.assign(2, thrift::test::Bonk());
+ l.bonk[0].__set_message("a");
+ l.bonk[1].__set_message("b");
+
+ BOOST_CHECK_EQUAL(to_string(l),
+ "ListBonks(bonk=[Bonk(message=a, type=0), Bonk(message=b, type=0)])");
+}
+
+BOOST_AUTO_TEST_SUITE_END()