reorganisation(#985): move basic typeString implementation into lib::meta
- simple function to pick up the mangled type - pretty-printing is implemented in format-obj.cpp - also move the demangleCxx()-Function to that location, it starts to be used for real, outside the test framework
This commit is contained in:
parent
f077c14d47
commit
0c4495a451
13 changed files with 301 additions and 113 deletions
|
|
@ -81,6 +81,7 @@ typedef unsigned int uint;
|
|||
using lib::diff::GenNode;
|
||||
using lib::P;
|
||||
using lib::meta::enable_if;
|
||||
using lib::meta::typeStr;
|
||||
using lib::meta::can_convertToString;
|
||||
|
||||
using std::string;
|
||||
|
|
@ -93,28 +94,11 @@ using std::endl;
|
|||
|
||||
|
||||
|
||||
///////////////////////////////copied from format-util.hpp
|
||||
template<typename TY>
|
||||
inline string
|
||||
typeStr (const TY* obj=0)
|
||||
{
|
||||
auto mangledType = obj? typeid(obj).name()
|
||||
: typeid(TY).name();
|
||||
return string("«")+ mangledType +"»";
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
inline string
|
||||
typeStr (TY const& ref)
|
||||
{ return typeStr(&ref); }
|
||||
///////////////////////////////copied from format-util.hpp
|
||||
|
||||
|
||||
///////////////////////////////planned minimal conversion, maybe in meta/util.hpp ?
|
||||
template<typename X, typename COND =void>
|
||||
struct CustomStringConv
|
||||
{
|
||||
static string invoke (X const& x) { return typeStr(x); }
|
||||
static string invoke (X const& x) { return "«"+typeStr(x)+"»"; }
|
||||
};
|
||||
|
||||
template<typename X>
|
||||
|
|
@ -134,7 +118,7 @@ inline string
|
|||
stringz (P<X> ptr)
|
||||
{
|
||||
if (not ptr)
|
||||
return "⟂ P"+typeStr(ptr.get());
|
||||
return "⟂ P<"+typeStr(ptr.get())+">";
|
||||
else
|
||||
return CustomStringConv<X>::invoke (*ptr);
|
||||
}
|
||||
|
|
@ -202,7 +186,7 @@ namespace meta {
|
|||
if (ptr)
|
||||
return os << (void*)ptr << " ↗" << *ptr;
|
||||
else
|
||||
return os << "⟂ " << typeStr<X>();
|
||||
return os << "⟂ «" << typeStr<X>() << "»";
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
|
|
|
|||
152
src/lib/format-obj.cpp
Normal file
152
src/lib/format-obj.cpp
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
FormatObj - simple means to display an object
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2016, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
/** @file format-obj.cpp
|
||||
** Some implementation helpers for simple object display.
|
||||
** This file provides some basic implementation functions, which
|
||||
** can be called from a generic front-end (header). The reason we
|
||||
** stash away some functions into an implementation unit is to keep
|
||||
** the include overhead low, which helps to reduce both code size
|
||||
** and compilation time. The functions here perform some formatting
|
||||
** tasks commonly used from debugging and diagnostics code, both to
|
||||
** investigate object contents and show types and addresses. They
|
||||
** are referred from our [lightweight string converter](\ref
|
||||
** lib::meta::CustomStringConv), but also from the util::toString()
|
||||
** function and more common [formatting utils](format-util.hpp).
|
||||
**
|
||||
** @see FormatHelper_test
|
||||
** @see FormatString_test
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/format-obj.hpp"
|
||||
#include "lib/unique-malloc-owner.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
|
||||
#ifdef __GNUG__
|
||||
/**
|
||||
* \par Implementation notes
|
||||
* GCC / G++ subscribes to a cross-vendor ABI for C++, sometimes called the IA64 ABI
|
||||
* because it happens to be the native ABI for that platform. It is summarised at
|
||||
* \link http://www.codesourcery.com/cxx-abi/ mentor-embedded \endlink
|
||||
* along with the current specification. For users of GCC greater than or equal to 3.x,
|
||||
* entry points are exposed through the standard library in `<cxxabi.h>`
|
||||
*
|
||||
* This implementation relies on a vendor neutral ABI for C++ compiled programs
|
||||
*
|
||||
* char* abi::__cxa_demangle(const char* mangled_name,
|
||||
* char* output_buffer, size_t* length,
|
||||
* int* status)
|
||||
*
|
||||
* Parameters:
|
||||
* - \c mangled_name
|
||||
* NUL-terminated character string containing the name to be demangled.
|
||||
* - \c output_buffer
|
||||
* region of memory, allocated with \c malloc, of `*length` bytes,
|
||||
* into which the demangled name is stored. If \c output_buffer is not long enough,
|
||||
* it is expanded using \c realloc. output_buffer may instead be NULL; in that case,
|
||||
* the demangled name is placed in a region of memory allocated with \c malloc.
|
||||
* - \c length
|
||||
* If length is non-NULL, the length of the buffer containing the demangled name is placed in `*length`.
|
||||
* - \c status
|
||||
* error flag: `*status` is set to one of the following values:
|
||||
*
|
||||
* 0: The demangling operation succeeded.
|
||||
* -1: A memory allocation failure occurred.
|
||||
* -2: mangled_name is not a valid name under the C++ ABI mangling rules.
|
||||
* -3: One of the arguments is invalid.
|
||||
*
|
||||
* The function returns a pointer to the start of the NUL-terminated demangled name,
|
||||
* or NULL if the demangling fails. The caller is responsible for deallocating
|
||||
* this memory using \c free.
|
||||
*/
|
||||
string
|
||||
demangleCxx (Literal rawName)
|
||||
{
|
||||
int error = -4;
|
||||
UniqueMallocOwner<char> demangled (abi::__cxa_demangle (rawName,
|
||||
NULL,
|
||||
NULL,
|
||||
&error));
|
||||
return 0==error? demangled.get()
|
||||
: string(rawName);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#warning "Lumiera was _not_ built with a GCC compatible compiler."
|
||||
#warning "There are good chances this works without problems, but up to now, \
|
||||
the Lumiera developers lacked the resources to investigate that option; \
|
||||
apologies for that."
|
||||
|
||||
/** Fallback type-ID:
|
||||
* @return unaltered internal type-ID
|
||||
*/
|
||||
string
|
||||
demangleCxx (Literal rawName)
|
||||
{
|
||||
return string (rawName);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
string
|
||||
humanReadableTypeID (Literal rawType)
|
||||
{
|
||||
string typeName = demangleCxx (rawType);
|
||||
return typeName;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
namespace util {
|
||||
|
||||
|
||||
namespace { // implementation details...
|
||||
|
||||
}//(End) implementation details
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} // namespace util
|
||||
79
src/lib/format-obj.hpp
Normal file
79
src/lib/format-obj.hpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
FORMAT-OBJ.hpp - simple means to display an object
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2016, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file format-obj.hpp
|
||||
** Simple functions to represent objects, for debugging and diagnostics.
|
||||
** The helpers provided here are rather commonplace, but written in a way
|
||||
** as to incur a rather modest header inclusion load. It should be OK to
|
||||
** use these even on widely used interface headers.
|
||||
** - util::toString() performs a failsafe to-String conversion, thereby preferring a
|
||||
** built-in conversion operator, falling back to a lexical conversion (boost)
|
||||
** or just a unmangled and simplified type string as default.
|
||||
** - lib::meta::demangleCxx() uses the built-in compiler support to translate a mangled
|
||||
** type-ID (as given by `typeid(TY).name()`) into a readable, fully qualified
|
||||
** C++ type name. This is only supported for GNU compatible compilers.
|
||||
**
|
||||
** @see FormatHelper_test
|
||||
** @see [frontend for boost::format, printf-style](format-string.hpp)
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_FORMAT_OBJ_H
|
||||
#define LIB_FORMAT_OBJ_H
|
||||
|
||||
#include "lib/meta/trait.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
||||
namespace lib {
|
||||
class Literal;
|
||||
|
||||
namespace meta {
|
||||
|
||||
/** reverse the effect of C++ name mangling.
|
||||
* @return string in language-level form of a C++ type or object name,
|
||||
* or a string with the original input if demangling fails.
|
||||
* @warning implementation relies on the cross vendor C++ ABI in use
|
||||
* by GCC and compatible compilers, so portability is limited.
|
||||
* The implementation is accessed through libStdC++
|
||||
* Name representation in emitted object code and type IDs is
|
||||
* essentially an implementation detail and subject to change.
|
||||
*/
|
||||
std::string demangleCxx (lib::Literal rawName);
|
||||
|
||||
|
||||
std::string humanReadableTypeID (lib::Literal);
|
||||
|
||||
}} // namespace lib::meta
|
||||
|
||||
|
||||
namespace util {
|
||||
|
||||
|
||||
|
||||
} // namespace util
|
||||
#endif /*LIB_FORMAT_OBJ_H*/
|
||||
|
|
@ -91,13 +91,13 @@
|
|||
** \endcode
|
||||
**
|
||||
** @remarks See the unit-test for extensive usage examples and corner cases.
|
||||
** The header format-conv.hpp provides an alternative string conversion,
|
||||
** using a bit of boost type traits and lexical_cast, but no boost::format.
|
||||
** The header format-obj.hpp provides an alternative string conversion,
|
||||
** using a bit of type traits and boost lexical_cast, but no boost::format.
|
||||
** @warning not suited for performance critical code. About 10 times slower than printf.
|
||||
**
|
||||
** @see FormatString_test
|
||||
** @see format-util.hpp
|
||||
** @see format-conv.hpp
|
||||
** @see format-obj.hpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "lib/hash-standard.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/format-obj.hpp"
|
||||
#include "lib/itertools.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -52,11 +53,6 @@
|
|||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{ // see test-helper.cpp
|
||||
std::string demangleCxx (lib::Literal rawName);
|
||||
}}
|
||||
|
||||
|
||||
namespace util {
|
||||
|
||||
|
|
@ -159,7 +155,7 @@ namespace util {
|
|||
{
|
||||
auto mangledType = obj? typeid(obj).name()
|
||||
: typeid(TY).name();
|
||||
string typeName = lib::test::demangleCxx (mangledType);
|
||||
string typeName = lib::meta::demangleCxx (mangledType);
|
||||
removePrefix (typeName, "const ");
|
||||
removeSuffix (typeName, " const*");
|
||||
return "«"+ typeName +"»";
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "lib/idi/genfunc.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/format-obj.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -34,15 +35,12 @@ using std::string;
|
|||
|
||||
|
||||
namespace lib {
|
||||
namespace test{ // see test-helper.cpp
|
||||
std::string demangleCxx (lib::Literal rawName);
|
||||
}
|
||||
namespace idi {
|
||||
|
||||
|
||||
namespace format { // generic entry points / integration helpers...
|
||||
|
||||
using lib::test::demangleCxx;
|
||||
using lib::meta::demangleCxx;
|
||||
|
||||
string
|
||||
demangled_innermost_component (const char* rawName)
|
||||
|
|
@ -59,7 +57,7 @@ namespace idi {
|
|||
string
|
||||
demangled_sanitised_name (const char* rawName)
|
||||
{
|
||||
return util::sanitise (test::demangleCxx (rawName));
|
||||
return util::sanitise (demangleCxx (rawName));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -82,4 +80,4 @@ namespace idi {
|
|||
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
}} // namespace lib::idi
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ namespace std { // forward declaration for std::string...
|
|||
|
||||
|
||||
namespace lib {
|
||||
class Literal;
|
||||
class Symbol;
|
||||
|
||||
namespace meta {
|
||||
|
||||
/* === conditional definition selector === */
|
||||
|
|
@ -154,7 +157,6 @@ namespace meta {
|
|||
|
||||
|
||||
|
||||
|
||||
/** Trait template for detecting a typelist type.
|
||||
* For example, this allows to write specialisations with the help of
|
||||
* boost::enable_if
|
||||
|
|
@ -173,5 +175,50 @@ namespace meta {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ==== generic string representation ==== */
|
||||
|
||||
/** pretty-print an internal C++ type representation
|
||||
* @see \ref format-obj.cpp implementation
|
||||
*/
|
||||
std::string humanReadableTypeID (lib::Literal);
|
||||
|
||||
std::string demangleCxx (lib::Literal rawName);
|
||||
|
||||
|
||||
|
||||
/** failsafe human readable type display
|
||||
* @return string representing the C++ type.
|
||||
* @remarks the purpose of this function is diagnostics
|
||||
* and unit-testing. When possible, RTTI is exposed, otherwise
|
||||
* the implementation falls back on the static type as seen by
|
||||
* the compiler on usage site. An attempt is made to de-mangle
|
||||
* and further simplify the type string, leaving out some common
|
||||
* (hard wired) namespace prefixes, and stripping typical adornments
|
||||
* like `const`, `*` and `&`
|
||||
* @warning this function does string transformations behind the scenes,
|
||||
* and thus should not be used in performance critical context. Moreover,
|
||||
* the returned type string is not necessarily exact and re-parsable.
|
||||
*/
|
||||
template<typename TY>
|
||||
inline std::string
|
||||
typeStr (const TY* obj=nullptr)
|
||||
{
|
||||
auto mangledType = obj? typeid(obj).name()
|
||||
: typeid(TY).name();
|
||||
return humanReadableTypeID (mangledType);
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
inline std::string
|
||||
typeStr (TY const& ref)
|
||||
{
|
||||
return typeStr (&ref);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::meta
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace test {
|
|||
using util::isnil;
|
||||
using util::contains;
|
||||
using lib::test::showType;
|
||||
using lib::test::demangleCxx;
|
||||
using lib::meta::demangleCxx;
|
||||
|
||||
typedef map<string, Launcher*> TestMap;
|
||||
typedef shared_ptr<TestMap> PTestMap;
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@
|
|||
#include "lib/format-string.hpp"
|
||||
#include "lib/unique-malloc-owner.hpp"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
|
@ -55,62 +51,6 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
#ifdef __GNUG__
|
||||
/**
|
||||
* \par Implementation notes
|
||||
* GCC / G++ subscribes to a cross-vendor ABI for C++, sometimes called the IA64 ABI
|
||||
* because it happens to be the native ABI for that platform. It is summarised at
|
||||
* \link http://www.codesourcery.com/cxx-abi/ mentor-embedded \endlink
|
||||
* along with the current specification. For users of GCC greater than or equal to 3.x,
|
||||
* entry points are exposed through the standard library in `<cxxabi.h>`
|
||||
*
|
||||
* This implementation relies on a vendor neutral ABI for C++ compiled programs
|
||||
*
|
||||
* char* abi::__cxa_demangle(const char* mangled_name,
|
||||
* char* output_buffer, size_t* length,
|
||||
* int* status)
|
||||
*
|
||||
* Parameters:
|
||||
* - \c mangled_name
|
||||
* NUL-terminated character string containing the name to be demangled.
|
||||
* - \c output_buffer
|
||||
* region of memory, allocated with \c malloc, of `*length` bytes,
|
||||
* into which the demangled name is stored. If \c output_buffer is not long enough,
|
||||
* it is expanded using \c realloc. output_buffer may instead be NULL; in that case,
|
||||
* the demangled name is placed in a region of memory allocated with \c malloc.
|
||||
* - \c length
|
||||
* If length is non-NULL, the length of the buffer containing the demangled name is placed in `*length`.
|
||||
* - \c status
|
||||
* error flag: `*status` is set to one of the following values:
|
||||
*
|
||||
* 0: The demangling operation succeeded.
|
||||
* -1: A memory allocation failure occurred.
|
||||
* -2: mangled_name is not a valid name under the C++ ABI mangling rules.
|
||||
* -3: One of the arguments is invalid.
|
||||
*
|
||||
* The function returns a pointer to the start of the NUL-terminated demangled name,
|
||||
* or NULL if the demangling fails. The caller is responsible for deallocating
|
||||
* this memory using \c free.
|
||||
*/
|
||||
string
|
||||
demangleCxx (Literal rawName)
|
||||
{
|
||||
int error = -4;
|
||||
UniqueMallocOwner<char> demangled (abi::__cxa_demangle (rawName,
|
||||
NULL,
|
||||
NULL,
|
||||
&error));
|
||||
return 0==error? demangled.get()
|
||||
: string(rawName);
|
||||
}
|
||||
|
||||
#else
|
||||
string
|
||||
demangleCxx (Literal rawName)
|
||||
{
|
||||
return string (rawName);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
** Mostly, these are diagnostics helpers to produce readable output, especially
|
||||
** for types. Some of these support meta programming to figure out the \em actual
|
||||
** reference kind (value, lvalue, rvalue) of a template parameter instantiation.
|
||||
** For GNU compatible compilers, we define here also an interface to the internal
|
||||
** For GNU compatible compilers, we provide here also an interface to the internal
|
||||
** ABI for [demangling type names](\ref demangleCxx).
|
||||
**
|
||||
** @note this header is included into a large number of tests.
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/format-obj.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <typeinfo>
|
||||
|
|
@ -56,6 +57,7 @@ namespace test{
|
|||
using lib::Literal;
|
||||
using std::string;
|
||||
using std::rand;
|
||||
using lib::meta::demangleCxx;
|
||||
|
||||
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ namespace test{
|
|||
* @return either the literal name without any further magic,
|
||||
* or the result of compile-time or run time
|
||||
* type identification as implemented by the compiler.
|
||||
* @deprecated 1/2016 to be replaced by lib::typeString (from \ref format-obj.hpp=
|
||||
*/
|
||||
template<typename T>
|
||||
inline Literal
|
||||
|
|
@ -78,6 +81,7 @@ namespace test{
|
|||
* @return either the literal name without any further magic,
|
||||
* or the result of compile-time or run time
|
||||
* type identification as implemented by the compiler.
|
||||
* @deprecated 1/2016 to be replaced by lib::typeString (from \ref format-obj.hpp=
|
||||
*/
|
||||
template<typename T>
|
||||
inline Literal
|
||||
|
|
@ -87,18 +91,6 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
/** reverse the effect of C++ name mangling.
|
||||
* @return string in language-level form of a C++ type or object name,
|
||||
* or a string with the original input if demangling fails.
|
||||
* @warning implementation relies on the cross vendor C++ ABI in use
|
||||
* by GCC and compatible compilers, so portability is limited.
|
||||
* The implementation is accessed through libStdC++
|
||||
* Name representation in emitted object code and type IDs is
|
||||
* essentially an implementation detail and subject to change.
|
||||
*/
|
||||
string
|
||||
demangleCxx (Literal rawName);
|
||||
|
||||
|
||||
/** short yet distinct name identifying the given type.
|
||||
* @return demangled type-id without any scopes. */
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
** mostly for the purpose of documenting the issue at the
|
||||
** usage site.
|
||||
**
|
||||
** @see lib::test::demangleCxx
|
||||
** @see lib::meta::demangleCxx
|
||||
** @see UniqueMallocOwner_test
|
||||
**
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ using std::cout;
|
|||
using std::endl;
|
||||
|
||||
using lib::test::showType;
|
||||
using lib::test::demangleCxx;
|
||||
using lib::meta::demangleCxx;
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace test{
|
|||
* and the ownership token should be empty.
|
||||
*
|
||||
* @see lib::UniqueMallocOwner
|
||||
* @see lib::test::demangleCxx
|
||||
* @see lib::meta::demangleCxx
|
||||
*/
|
||||
class UniqueMallocOwner_test : public Test
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue