Fix printing of collections. Make it impossible for a collection with 1 element to match the string of an empty collection. Avoid checking if comma needs to be added in loop. Make an empty tuple print same as empty collection: '{}'.
Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
@@ -78,59 +78,18 @@ namespace cling {
|
|||||||
// cling::Value
|
// cling::Value
|
||||||
std::string printValue(const Value *value);
|
std::string printValue(const Value *value);
|
||||||
|
|
||||||
// Collections internal declaration
|
namespace valuePrinterInternal {
|
||||||
namespace collectionPrinterInternal {
|
extern const char* const kEmptyCollection;
|
||||||
// Maps declaration
|
|
||||||
template<typename CollectionType>
|
|
||||||
auto printValue_impl(const CollectionType *obj, short)
|
|
||||||
-> decltype(
|
|
||||||
++(obj->begin()), obj->end(),
|
|
||||||
obj->begin()->first, obj->begin()->second,
|
|
||||||
std::string());
|
|
||||||
|
|
||||||
// Vector, set, deque etc. declaration.
|
|
||||||
template<typename CollectionType>
|
|
||||||
auto printValue_impl(const CollectionType *obj, int)
|
|
||||||
-> decltype(
|
|
||||||
++(obj->begin()), obj->end(),
|
|
||||||
*(obj->begin()), &(*(obj->begin())),
|
|
||||||
std::string());
|
|
||||||
|
|
||||||
// As above, but without ability to take address of elements.
|
|
||||||
template<typename CollectionType>
|
|
||||||
auto printValue_impl(const CollectionType *obj, long)
|
|
||||||
-> decltype(
|
|
||||||
++(obj->begin()), obj->end(),
|
|
||||||
*(obj->begin()),
|
|
||||||
std::string());
|
|
||||||
|
|
||||||
// No general fallback anymore here, void* overload used for that now
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collections
|
|
||||||
template<typename CollectionType>
|
|
||||||
auto printValue(const CollectionType *obj)
|
|
||||||
-> decltype(collectionPrinterInternal::printValue_impl(obj, 0), std::string())
|
|
||||||
{
|
|
||||||
return collectionPrinterInternal::printValue_impl(obj, (short)0); // short -> int -> long = priority order
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arrays
|
|
||||||
template<typename T, size_t N>
|
|
||||||
std::string printValue(const T (*obj)[N]) {
|
|
||||||
std::string str = "{ ";
|
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i) {
|
|
||||||
str += printValue(*obj + i);
|
|
||||||
if (i < N - 1) str += ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
return str + " }";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collections internal
|
// Collections internal
|
||||||
namespace collectionPrinterInternal {
|
namespace collectionPrinterInternal {
|
||||||
// Maps
|
// Maps
|
||||||
|
template<typename Pair>
|
||||||
|
std::string printPair(const Pair& P) {
|
||||||
|
return printValue(&P->first) + " => " + printValue(&P->second);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename CollectionType>
|
template<typename CollectionType>
|
||||||
auto printValue_impl(const CollectionType *obj, short)
|
auto printValue_impl(const CollectionType *obj, short)
|
||||||
-> decltype(
|
-> decltype(
|
||||||
@@ -138,20 +97,17 @@ namespace cling {
|
|||||||
obj->begin()->first, obj->begin()->second,
|
obj->begin()->first, obj->begin()->second,
|
||||||
std::string())
|
std::string())
|
||||||
{
|
{
|
||||||
std::string str = "{ ";
|
|
||||||
|
|
||||||
auto iter = obj->begin();
|
auto iter = obj->begin();
|
||||||
auto iterEnd = obj->end();
|
auto iterEnd = obj->end();
|
||||||
while (iter != iterEnd) {
|
if (iter == iterEnd)
|
||||||
str += printValue(&iter->first);
|
return valuePrinterInternal::kEmptyCollection;
|
||||||
str += " => ";
|
|
||||||
str += printValue(&iter->second);
|
|
||||||
++iter;
|
|
||||||
if (iter != iterEnd) {
|
|
||||||
str += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
std::string str("{ ");
|
||||||
|
str += printPair(*iter);
|
||||||
|
while (++iter != iterEnd) {
|
||||||
|
str += ", ";
|
||||||
|
str += printPair(*iter);
|
||||||
|
}
|
||||||
return str + " }";
|
return str + " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,18 +119,17 @@ namespace cling {
|
|||||||
*(obj->begin()), &(*(obj->begin())),
|
*(obj->begin()), &(*(obj->begin())),
|
||||||
std::string())
|
std::string())
|
||||||
{
|
{
|
||||||
std::string str = "{ ";
|
|
||||||
|
|
||||||
auto iter = obj->begin();
|
auto iter = obj->begin();
|
||||||
auto iterEnd = obj->end();
|
auto iterEnd = obj->end();
|
||||||
while (iter != iterEnd) {
|
if (iter == iterEnd)
|
||||||
str += printValue(&(*iter));
|
return valuePrinterInternal::kEmptyCollection;
|
||||||
++iter;
|
|
||||||
if (iter != iterEnd) {
|
|
||||||
str += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
std::string str("{ ");
|
||||||
|
str += printValue(&(*iter));
|
||||||
|
while (++iter != iterEnd) {
|
||||||
|
str += ", ";
|
||||||
|
str += printValue(&(*iter));
|
||||||
|
}
|
||||||
return str + " }";
|
return str + " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,22 +141,45 @@ namespace cling {
|
|||||||
*(obj->begin()),
|
*(obj->begin()),
|
||||||
std::string())
|
std::string())
|
||||||
{
|
{
|
||||||
std::string str = "{ ";
|
auto iter = obj->begin();
|
||||||
|
auto iterEnd = obj->end();
|
||||||
|
if (iter == iterEnd)
|
||||||
|
return valuePrinterInternal::kEmptyCollection;
|
||||||
|
|
||||||
auto iter = obj->begin();
|
std::string str("{ ");
|
||||||
auto iterEnd = obj->end();
|
const auto value0 = (*iter);
|
||||||
while (iter != iterEnd) {
|
str += printValue(&value0);
|
||||||
const auto value = (*iter);
|
while (++iter != iterEnd) {
|
||||||
str += printValue(&value);
|
const auto valueN = (*iter);
|
||||||
++iter;
|
str += ", ";
|
||||||
if (iter != iterEnd) {
|
str += printValue(&valueN);
|
||||||
str += ", ";
|
}
|
||||||
}
|
return str + " }";
|
||||||
}
|
|
||||||
|
|
||||||
return str + " }";
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collections
|
||||||
|
template<typename CollectionType>
|
||||||
|
auto printValue(const CollectionType *obj)
|
||||||
|
-> decltype(collectionPrinterInternal::printValue_impl(obj, 0), std::string())
|
||||||
|
{
|
||||||
|
// short -> int -> long = priority order
|
||||||
|
return collectionPrinterInternal::printValue_impl(obj, (short)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrays
|
||||||
|
template<typename T, size_t N>
|
||||||
|
std::string printValue(const T (*obj)[N]) {
|
||||||
|
if (N == 0)
|
||||||
|
return valuePrinterInternal::kEmptyCollection;
|
||||||
|
|
||||||
|
std::string str = "{ ";
|
||||||
|
str += printValue(*obj + 0);
|
||||||
|
for (size_t i = 1; i < N; ++i) {
|
||||||
|
str += ", ";
|
||||||
|
str += printValue(*obj + i);
|
||||||
|
}
|
||||||
|
return str + " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tuples
|
// Tuples
|
||||||
@@ -269,6 +247,8 @@ namespace cling {
|
|||||||
std::string printValue(std::tuple<ARGS...> *val)
|
std::string printValue(std::tuple<ARGS...> *val)
|
||||||
{
|
{
|
||||||
using T = std::tuple<ARGS...>;
|
using T = std::tuple<ARGS...>;
|
||||||
|
if (std::tuple_size<T>::value == 0)
|
||||||
|
return valuePrinterInternal::kEmptyCollection;
|
||||||
return collectionPrinterInternal::tuplePairPrintValue<T>(val);
|
return collectionPrinterInternal::tuplePairPrintValue<T>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,13 @@ extern "C" void cling_PrintValue(void * /*cling::Value**/ V) {
|
|||||||
//std::string valueStr = printValueInternal(*value);
|
//std::string valueStr = printValueInternal(*value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exported for RuntimePrintValue.h
|
||||||
|
namespace cling {
|
||||||
|
namespace valuePrinterInternal {
|
||||||
|
extern const char* const kEmptyCollection = "{}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static std::string enclose(const std::string& Mid, const char* Begin,
|
static std::string enclose(const std::string& Mid, const char* Begin,
|
||||||
|
38
test/Prompt/ValuePrinter/Collections.C
Normal file
38
test/Prompt/ValuePrinter/Collections.C
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CLING - the C++ LLVM-based InterpreterG :)
|
||||||
|
//
|
||||||
|
// This file is dual-licensed: you can choose to license it under the University
|
||||||
|
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
||||||
|
// LICENSE.TXT for details.
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// RUN: cat %s | %cling -Xclang -verify 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::vector<bool> Bv(5,5)
|
||||||
|
// FIXME: Printing std::vector<bool> is still broken.
|
||||||
|
// But the line above at least tests cling doesn't crash because of it.
|
||||||
|
// BROKENCHECK: (std::vector<bool> &) { true, true, true, true, true }
|
||||||
|
|
||||||
|
class CustomThing {
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace cling {
|
||||||
|
std::string printValue(const CustomThing *ptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CustomThing> A, B(1);
|
||||||
|
cling::printValue(&A) == cling::printValue(&B)
|
||||||
|
// CHECK: (bool) false
|
||||||
|
|
||||||
|
std::tuple<> tA
|
||||||
|
// CHECK: (std::tuple<> &) {}
|
||||||
|
|
||||||
|
// expected-no-diagnostics
|
||||||
|
.q
|
@@ -20,7 +20,7 @@ std::make_pair(4L,'c')
|
|||||||
//CHECK: (std::pair<{{.*long.*,.*char.*}}>) { 4, 'c' }
|
//CHECK: (std::pair<{{.*long.*,.*char.*}}>) { 4, 'c' }
|
||||||
|
|
||||||
std::make_tuple()
|
std::make_tuple()
|
||||||
//CHECK: (std::tuple<>) { }
|
//CHECK: (std::tuple<>) {}
|
||||||
|
|
||||||
std::make_tuple(2)
|
std::make_tuple(2)
|
||||||
//CHECK: (std::tuple<{{.*int.*}}>) { 2 }
|
//CHECK: (std::tuple<{{.*int.*}}>) { 2 }
|
||||||
|
@@ -39,6 +39,8 @@ set_target_properties(cling
|
|||||||
if(MSVC)
|
if(MSVC)
|
||||||
set_target_properties(cling
|
set_target_properties(cling
|
||||||
PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1)
|
PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1)
|
||||||
|
set_property(TARGET cling APPEND_STRING PROPERTY LINK_FLAGS
|
||||||
|
" /EXPORT:?kEmptyCollection@valuePrinterInternal@cling@@3QEBDEB ")
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
target_link_libraries(cling
|
target_link_libraries(cling
|
||||||
|
Reference in New Issue
Block a user