formatting(#985): use custom string conversion with smart-ptr

our lib::P smart-pointer is built on top of std::shared_ptr,
while additionally delegating comparisons to the pointee.

In a similar vein, I've now added a custom string conversion,
delegating to the pointee, with a type-string as fallback.

Together with the built-in string conversion for output streams,
we should now be able to remove most of the explicit string
conversions and calls to util::str in all of our test code.

This removes the last roadblock towards disentangling the
pretty-printing header includes, which in turn should allow
us to remove any conditional code in the built-in string
conversion of GenNode, Variant and the like. Which basically
was the objective for ticket #985
This commit is contained in:
Fischlurch 2016-01-06 04:59:43 +01:00
parent 2cf127e16a
commit ed92b92158
2 changed files with 32 additions and 37 deletions

View file

@ -79,22 +79,17 @@ typedef unsigned int uint;
#include <utility>
#include <string>
using lib::diff::GenNode;
using lib::P;
using lib::meta::enable_if;
using lib::meta::typeStr;
using lib::diff::GenNode;
using lib::meta::is_basically;
using lib::meta::is_StringLike;
using lib::meta::can_lexical2string;
using lib::meta::can_convertToString;
using lib::meta::use_StringConversion4Stream;
using lib::meta::CustomStringConv;
using lib::meta::Strip;
using std::__and_;
using std::__not_;
using std::string;
using std::cout;
using std::endl;
@ -102,30 +97,6 @@ using std::endl;
///////////////////////////////shall go into the implementation of lib::P
template<typename X>
inline string
stringz (P<X> ptr)
{
if (not ptr)
return "⟂ P<"+typeStr(ptr.get())+">";
else
return CustomStringConv<X>::invoke (*ptr);
}
namespace std {
template<typename X>
std::ostream&
operator<< (std::ostream& os, P<X> const& ptr)
{
return os << stringz (ptr);
}
}
class Reticent
{
uint neigh_ = 42;
@ -144,7 +115,7 @@ newP (ARGS&&... ctorArgs)
template<typename T>
using BasicallyString = is_basically<T, string>;
template<typename T>
using BasicallyChar = is_basically<typename std::remove_all_extents<T>::type, char>;
using BasicallyChar = std::is_convertible<T, const char*>;
void
@ -154,11 +125,12 @@ showTypes()
#define SHOW_CHECK(_EXPR_) cout << STRINGIFY(_EXPR_) << "\t : " << (_EXPR_::value? "Yes":"No") << endl;
#define ANALYSE(_TYPE_) \
cout << "Type: " STRINGIFY(_TYPE_) " ......"<<endl; \
SHOW_CHECK (BasicallyChar<_TYPE_>); \
SHOW_CHECK (BasicallyString<_TYPE_>); \
SHOW_CHECK (std::is_arithmetic<_TYPE_>);\
SHOW_CHECK (can_lexical2string<_TYPE_>); \
SHOW_CHECK (can_convertToString<_TYPE_>); \
SHOW_CHECK (is_StringLike<_TYPE_>); \
SHOW_CHECK (BasicallyChar<_TYPE_>); \
SHOW_CHECK (BasicallyString<_TYPE_>); \
SHOW_CHECK (std::is_arithmetic<_TYPE_>); \
SHOW_CHECK (can_lexical2string<_TYPE_>); \
SHOW_CHECK (can_convertToString<_TYPE_>); \
SHOW_CHECK (use_StringConversion4Stream<_TYPE_>);

View file

@ -51,6 +51,8 @@
#include "lib/error.hpp"
#include "lib/meta/util.hpp"
#include <memory>
@ -98,6 +100,8 @@ namespace lib {
void swap(P& b) { BASE::swap (b);}
operator std::string() const noexcept;
private: /* === friend operators injected into enclosing namespace for ADL === */
//////////////////TICKET #932 Clang is unable to fill in the default template argument. Resolved in newer versions of Clang. Temporary workaround: add second parameter B
@ -128,5 +132,24 @@ namespace lib {
};
/**
* use custom string conversion on pointee, if applicable,
* otherwise fall back to a human readable type string.S
*/
template<class TAR, class BASE>
inline
P<TAR,BASE>::operator std::string() const noexcept
try {
if (this->get())
return meta::CustomStringConv<TAR>::invoke (this->operator*());
else
return "⟂ P<"+meta::typeStr(this->get())+">";
}
catch(...)
{ return ""; }
} // namespace lib
#endif