From 89928bc447fef19c66ceb8f45fbf2e5ca09ab6a0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 27 Dec 2011 01:25:09 +0100 Subject: [PATCH] refactor format-util: simplify picking the right specialisation --- src/lib/format-util.hpp | 105 ++++++++++++++++--------------- src/lib/meta/trait.hpp | 8 +-- tests/lib/format-helper-test.cpp | 14 ++--- 3 files changed, 64 insertions(+), 63 deletions(-) diff --git a/src/lib/format-util.hpp b/src/lib/format-util.hpp index 4aa0a1743..d1ef9d021 100644 --- a/src/lib/format-util.hpp +++ b/src/lib/format-util.hpp @@ -1,5 +1,5 @@ /* - FORMAT.hpp - helpers for formatting and diagnostics + FORMAT-UTIL.hpp - helpers for formatting and diagnostics Copyright (C) Lumiera.org 2009, Hermann Vosseler @@ -23,18 +23,23 @@ /** @file format.hpp ** Collection of small helpers and convenience shortcuts for diagnostics & formatting. + ** - util::str() performs a failsafe to-String conversion, thereby preferring a + ** built-in conversion operator, falling back to just a mangled type string. + ** - util::tyStr() generates a string corresponding to the type of the given object. + ** Currently just implemented through the mangled RTTI type string ** - ** @todo we could add a facade to boost::format here, see Ticket #166 + ** @see FormatHelper_test + ** @see format-string.hpp frontend for boost::format, printf-style ** */ -#ifndef UTIL_FORMAT_H -#define UTIL_FORMAT_H +#ifndef LIB_FORMAT_UTIL_H +#define LIB_FORMAT_UTIL_H -//#include "lib/util.hpp" #include "lib/meta/trait.hpp" #include "lib/symbol.hpp" +#include "lib/util.hpp" #include #include @@ -46,61 +51,65 @@ namespace util { + using boost::enable_if; using lib::meta::can_ToString; using lib::meta::can_lexical2string; using lib::Symbol; - using boost::enable_if; - using boost::disable_if; + using util::isnil; using std::string; namespace { // we need to guard the string conversion // to avoid a compiler error in case the type isn't convertible.... - template - inline string - invoke_2string ( typename enable_if< can_ToString, - X >::type const& val) - { - return string(val); - } template - inline string - invoke_2string ( typename disable_if< can_ToString, - X >::type const&) - { - return ""; - } - - + struct use_StringConversion : can_ToString { }; template - inline string - invoke_indirect2string ( typename enable_if< can_lexical2string, - X >::type const& val) - { - try { return boost::lexical_cast (val); } - catch(...) { return ""; } - } + struct use_LexicalConversion + { + enum { value = can_lexical2string::value + && !can_ToString::value + }; + }; + + + /** helper: reliably get some string representation for type X */ + template + struct _InvokeFailsafe + { + static string toString (X const&) { return ""; } + }; template - inline string - invoke_indirect2string ( typename disable_if< can_lexical2string, - X >::type const&) - { - return ""; - } - } + struct _InvokeFailsafe >::type> + { + static string + toString (X const& val) + try { return string(val); } + catch(...) { return ""; } + }; + + template + struct _InvokeFailsafe >::type> + { + static string + toString (X const& val) + try { return boost::lexical_cast (val); } + catch(...) { return ""; } + }; + }//(End) guards/helpers + /** try to get an object converted to string. - * An custom/standard conversion to string is used, + * A custom/standard conversion to string is used, * if applicable; otherwise, some standard types can be * converted by a lexical_cast (based on operator<< ). * Otherwise, either the fallback string is used, or just - * a string denoting the (mangled) type. + * a string based on the (mangled) type. */ template inline string @@ -109,24 +118,16 @@ namespace util { , Symbol fallback =0 /// < replacement text to show if string conversion fails ) { - if (can_ToString::value) - return string(prefix) + invoke_2string(val); - + string res = _InvokeFailsafe::toString(val); + if (!isnil (res)) + return string(prefix) + res; else - { - if (can_lexical2string::value) - { - string res (invoke_indirect2string (val)); - if ("" != res) - return string(prefix) + res; - } - - return fallback? string(fallback) - : tyStr(val); - } + return fallback? string(fallback) + : tyStr(val); } + /** @return a string denoting the type. */ template inline string diff --git a/src/lib/meta/trait.hpp b/src/lib/meta/trait.hpp index 0f25822fb..3c5ecbe0d 100644 --- a/src/lib/meta/trait.hpp +++ b/src/lib/meta/trait.hpp @@ -33,7 +33,7 @@ #include #include #include -#include + #include //Forward declarations for the Unwrap helper.... @@ -42,14 +42,14 @@ namespace boost{ } namespace std { namespace tr1 { - template class reference_wrapper; + template class reference_wrapper; template class shared_ptr; }} namespace lib{ - template class P; + template class P; } namespace mobject{ - template class Placement; + template class Placement; } diff --git a/tests/lib/format-helper-test.cpp b/tests/lib/format-helper-test.cpp index 9ca85d3ee..f223510af 100644 --- a/tests/lib/format-helper-test.cpp +++ b/tests/lib/format-helper-test.cpp @@ -35,8 +35,7 @@ namespace util { namespace test { class Reticent - { - }; + { }; class UnReticent : public Reticent @@ -47,10 +46,11 @@ namespace test { - /************************************************* - * verifies the proper working of helper functions - * frequently used within the Lumiera testsuite. - * @see test-helper.hpp + /******************************************************************************* + * @test verifies the proper working of some string-formatting helper functions. + * - util::str() provides a failsafe to-String conversion, preferring + * an built-in conversion, falling back to just a mangled type string. + * @see format-util.hpp */ class FormatHelper_test : public Test { @@ -61,7 +61,7 @@ namespace test { } - /** @test verify the maybe-to-string conversion. */ + /** @test verify a failasfe to-string conversion. */ void check2String () {