basically a working solution for toString in ostream
...and learned a lot about the new type_traits on the way. As it seems, it is not possible to get a clean error message when passing an "object" with no custom string conversion; instead, some overload for an rvalue-ostream kicks in. probably I'll go for shoing a type string in these cases
This commit is contained in:
parent
9f8ab48c51
commit
d09a5846d4
7 changed files with 101 additions and 8 deletions
|
|
@ -45,9 +45,11 @@ typedef unsigned int uint;
|
|||
//#include "lib/util.hpp"
|
||||
|
||||
#include "lib/meta/util.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
|
||||
#include <iostream>
|
||||
//#include <cstdarg>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
//#include <typeinfo>
|
||||
|
|
@ -136,14 +138,102 @@ stringz (P<X> ptr)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////reworked traits
|
||||
namespace {
|
||||
|
||||
using lib::meta::Strip;
|
||||
using std::__or_;
|
||||
using std::__and_;
|
||||
using std::__not_;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_basically
|
||||
: std::is_same <typename Strip<T>::TypePlain
|
||||
,typename Strip<U>::TypePlain>
|
||||
{ };
|
||||
|
||||
template<typename X>
|
||||
struct can_lexical2string
|
||||
: __or_< std::is_arithmetic<X>
|
||||
, is_basically<X, string>
|
||||
, is_basically<typename std::remove_all_extents<X>::type, char>
|
||||
>
|
||||
{ };
|
||||
}
|
||||
/////////////////////////////////////////reworked traits
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////planned new ostream inclusion
|
||||
namespace {
|
||||
|
||||
template<typename X>
|
||||
struct use_StringConversion
|
||||
{
|
||||
enum { value = can_convertToString<X>::value
|
||||
&& !can_lexical2string<X>::value
|
||||
};
|
||||
};
|
||||
|
||||
template<typename X>
|
||||
struct use_ObjectTypeIndicator
|
||||
: __and_<__not_<can_convertToString<X>>
|
||||
,__not_<can_lexical2string<X>>
|
||||
,std::is_object<X>
|
||||
>
|
||||
{ };
|
||||
}
|
||||
|
||||
template<typename X, typename = enable_if<use_StringConversion<X>>>
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, X const& obj)
|
||||
{
|
||||
return os << CustomStringConv<X>::invoke (obj);
|
||||
}
|
||||
//
|
||||
// template<typename X, typename = enable_if<use_ObjectTypeIndicator<X>>>
|
||||
// std::ostream&
|
||||
// operator<< (std::ostream& os, X const& obj)
|
||||
// {
|
||||
// return os << CustomStringConv<X>::invoke (obj);
|
||||
// }
|
||||
|
||||
template<typename X>
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, P<X> const& ptr)
|
||||
{
|
||||
return os << stringz (ptr);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////planned new ostream inclusion
|
||||
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
{
|
||||
auto psss = newP<Reticent>();
|
||||
auto gnng = newP<GenNode>("Hui", "Buh");
|
||||
|
||||
cout << "uiii..." << stringz(psss) <<endl;
|
||||
cout << "maui..." << stringz(gnng) <<endl;
|
||||
#define SHOW_CHECK(_EXPR_) cout << STRINGIFY(_EXPR_) << "\t : " << (_EXPR_::value? "Yes":"No") << endl;
|
||||
|
||||
using CharLit = typeof("bla");
|
||||
|
||||
using BasicallyString = is_basically<CharLit, string>;
|
||||
using BasicallyChar = is_basically<std::remove_all_extents<CharLit>::type, char>;
|
||||
|
||||
SHOW_CHECK (BasicallyChar);
|
||||
SHOW_CHECK (BasicallyString);
|
||||
SHOW_CHECK (std::is_arithmetic<CharLit>);
|
||||
SHOW_CHECK (can_lexical2string<CharLit>);
|
||||
SHOW_CHECK (can_convertToString<CharLit>);
|
||||
SHOW_CHECK (use_StringConversion<CharLit>);
|
||||
|
||||
cout << "mauu..." << psss <<endl;
|
||||
cout << "wauu..." << gnng <<endl;
|
||||
|
||||
// cout << "mauuu.." << *psss <<endl; ///////////does not compile (but error message is misleading)
|
||||
cout << "wauuu.." << *gnng <<endl;
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
|
||||
|
|
|
|||
|
|
@ -348,7 +348,10 @@ namespace asset {
|
|||
ID<KIND> ID<KIND>::INVALID = ID(0);
|
||||
|
||||
|
||||
/** convenient for debugging */
|
||||
/** convenient for debugging
|
||||
* @deprecated to be obsoleted by automatically using
|
||||
* custom string conversion in ostreams
|
||||
*/
|
||||
inline string str (PcAsset const& a)
|
||||
{
|
||||
if (a)
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ namespace control {
|
|||
ostream&
|
||||
dump (ostream& output) const
|
||||
{
|
||||
return BASE::dump (output << util::str (element()) << ',');
|
||||
return BASE::dump (output << util::str (element()) << ','); //////////////////TICKET #985 : make str obsolete!
|
||||
}
|
||||
|
||||
friend bool
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace asset {
|
|||
else
|
||||
{
|
||||
_Fmt fmt("%s %|50T.| id=%s adr=%p smart-ptr=%p use-count=%u");
|
||||
cout << fmt % str(aa) % aa->getID() % aa.get() % &aa % (aa.use_count() - 1) << "\n";
|
||||
cout << fmt % str(aa) % aa->getID() % aa.get() % &aa % (aa.use_count() - 1) << "\n"; ////////////TICKET #985 : make str obsolete
|
||||
} }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ namespace test {
|
|||
CHECK (com);
|
||||
CHECK (com == Command::get("test.command1.2"));
|
||||
CHECK (contains (str(com), "test.command1.2"));
|
||||
CHECK (contains (str(com), "{def}"));
|
||||
CHECK (contains (str(com), "{def}")); //////////////////TICKET #985 : make str obsolete!
|
||||
CHECK (!com.canExec());
|
||||
VERIFY_ERROR (UNBOUND_ARGUMENTS, com() );
|
||||
CHECK ( 0 == command1::check_);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace test {
|
|||
void treat (Clip& c)
|
||||
{
|
||||
Placement<Clip>& pC = getPlacement<Clip>();
|
||||
cout << "Clip on media : "<< str(pC->getMedia()) <<"\n";
|
||||
cout << "Clip on media : "<< str(pC->getMedia()) <<"\n"; //////////////////TICKET #985 : make str obsolete!
|
||||
CHECK (pC->operator==(c));
|
||||
log_ = string (pC);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ namespace test {
|
|||
// access MObject (Clip API)
|
||||
// cout << rMO->operator string() << endl; /////////////////////TICKET #428
|
||||
PMedia media = rMO->getMedia();
|
||||
cout << str(media) << endl; /////////////////////TICKET #520
|
||||
cout << str(media) << endl; /////////////////////TICKET #520 ///////TICKET #985 : make str obsolete!
|
||||
Duration mediaLength = media->getLength();
|
||||
CHECK (!isnil (mediaLength));
|
||||
CHECK (rMO->isValid());
|
||||
|
|
|
|||
Loading…
Reference in a new issue