From: g0dil Date: Fri, 13 Nov 2009 12:39:01 +0000 (+0000) Subject: Utils/Console: Parse char arguments as integers X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=a30f975608bae2dcee151af15dc7f40602627615;p=senf.git Utils/Console: Parse char arguments as integers git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1524 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Utils/Console/STLSupport.ct b/senf/Utils/Console/STLSupport.ct index 08116a0..108b974 100644 --- a/senf/Utils/Console/STLSupport.ct +++ b/senf/Utils/Console/STLSupport.ct @@ -40,12 +40,7 @@ template prefix_ std::string senf::console::detail::CollectionArgumentTraitsBase::description() { - std::string type (prettyName(typeid(Collection))); - std::string::size_type e (type.find('<')); - if (e == std::string::npos) e = type.size(); - std::string::size_type b (type.rfind(':', e)); - if (b == std::string::npos) b = 0; else ++b; - return type.substr(b,e-b) + "<" + return senf::prettyBaseName(typeid(Collection)) + "<" + ArgumentTraits::description() + ">"; } @@ -120,12 +115,7 @@ parse(ParseCommandInfo::TokensRange const & tokens, Collection & out) template prefix_ std::string senf::console::detail::MapArgumentTraits::description() { - std::string type (prettyName(typeid(Collection))); - std::string::size_type e (type.find('<')); - if (e == std::string::npos) e = type.size(); - std::string::size_type b (type.rfind(':', e)); - if (b == std::string::npos) b = 0; else ++b; - return type.substr(b,e-b) + "<" + return senf::prettyBaseName(typeid(Collection)) + "<" + ArgumentTraits::description() + "," + ArgumentTraits::description() + ">"; } diff --git a/senf/Utils/Console/Traits.ct b/senf/Utils/Console/Traits.ct index 8749e9a..6f90704 100644 --- a/senf/Utils/Console/Traits.ct +++ b/senf/Utils/Console/Traits.ct @@ -47,57 +47,6 @@ senf::console::senf_console_parse_argument(ParseCommandInfo::TokensRange const & return false; } -/////////////////////////////////////////////////////////////////////////// -// senf::console::ArgumentTraits< senf::console::FlagCollection > - -template -prefix_ void senf::console::ArgumentTraits< senf::console::FlagCollection >:: -parse(ParseCommandInfo::TokensRange const & tokens, type & out) -{ - CheckedArgumentIteratorWrapper arg (tokens); - out.value = 0; - while (arg) { - Enum v; - senf::console::parse( *(arg++), v); - out.value |= v; - } -} - -template -prefix_ std::string -senf::console::ArgumentTraits< senf::console::FlagCollection >::description() -{ - return ArgumentTraits::description(); -} - -template -prefix_ std::string -senf::console::ArgumentTraits< senf::console::FlagCollection >::str(type const & value) -{ - std::stringstream ss; - senf::console::format(value, ss); - return ss.str(); -} - -/////////////////////////////////////////////////////////////////////////// -// senf::console::ReturnValueTraits< senf::console::FlagCollection > - -template -prefix_ void senf::console::ReturnValueTraits< senf::console::FlagCollection >:: -format(type const & value, std::ostream & os) -{ - unsigned n (0); - std::stringstream ss; - unsigned long flag (1); - for (unsigned bit (0); bit(flag), ss); - } - } - os << (n != 1 ? "(" + ss.str() + ")" : ss.str()); -} - ///////////////////////////////ct.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Utils/Console/Traits.cti b/senf/Utils/Console/Traits.cti index 0173633..c96ae78 100644 --- a/senf/Utils/Console/Traits.cti +++ b/senf/Utils/Console/Traits.cti @@ -80,9 +80,7 @@ prefix_ void senf::console::format(Type const & value, std::ostream & os) template prefix_ std::string senf::console::ArgumentTraits::description() { - std::string type (prettyName(typeid(Type))); - std::string::size_type i (type.rfind(':')); - return i == std::string::npos ? type : type.substr(i+1); + return prettyBaseName(typeid(Type)); } template @@ -93,6 +91,24 @@ prefix_ std::string senf::console::ArgumentTraits::str(Type const & value) return ss.str(); } +/////////////////////////////////////////////////////////////////////////// +// senf::console::detail::CharArgumentTraits + +template +prefix_ void senf::console::detail::CharArgumentTraits:: +parse(ParseCommandInfo::TokensRange const & tokens, CharT & out) +{ + typename base::type v; + base::parse(tokens,v); + out = v; +} + +template +prefix_ std::string senf::console::detail::CharArgumentTraits::description() +{ + return prettyBaseName(typeid(CharT)); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/Utils/Console/Traits.hh b/senf/Utils/Console/Traits.hh index 811be19..19565b8 100644 --- a/senf/Utils/Console/Traits.hh +++ b/senf/Utils/Console/Traits.hh @@ -41,36 +41,6 @@ namespace senf { namespace console { - /** \brief Customize return value formating - - ReturnValueTraits provides return value formatting. The default implementation provided here - will forward the call directly to senf_console_format_value(). The default implementation of - that function will write the \a value to \a os using standard iostream formatting. - - To customize this behavior for some type, either provide an implementation of - senf_console_format_value() in the types namespace or provide a specialization of - ReturnValueTraits. - - The output should \e not end in a newline since one is added automatically. - */ - template - struct ReturnValueTraits - { - typedef Type type; - - static void format(Type const & value, std::ostream & os); - ///< Write \a value to \a os - }; - - /** \brief Return value formatter - - \see ReturnValuetraits - - \related ReturnValueTraits - */ - template - void senf_console_format_value(Type const & value, std::ostream & os); - /** \brief Customize argument parsing ArgumentTraits provides argument parsing, Additionally, this class provides a way to get a @@ -130,6 +100,38 @@ namespace console { template bool senf_console_parse_argument(ParseCommandInfo::TokensRange const & tokens, Type & out); + + /** \brief Customize return value formating + + ReturnValueTraits provides return value formatting. The default implementation provided here + will forward the call directly to senf_console_format_value(). The default implementation of + that function will write the \a value to \a os using standard iostream formatting. + + To customize this behavior for some type, either provide an implementation of + senf_console_format_value() in the types namespace or provide a specialization of + ReturnValueTraits. + + The output should \e not end in a newline since one is added automatically. + */ + template + struct ReturnValueTraits + { + typedef Type type; + + static void format(Type const & value, std::ostream & os); + ///< Write \a value to \a os + }; + + /** \brief Return value formatter + + \see ReturnValuetraits + + \related ReturnValueTraits + */ + template + void senf_console_format_value(Type const & value, std::ostream & os); + + /** \brief Parse token range This helper will invoke the correct ArgumentTraits::parse function to parse the input tokens @@ -159,55 +161,6 @@ namespace console { template void format(Type const & value, std::ostream & os); -#ifndef DOXYGEN - - // Parse bool: true/false, yes/no, enabled/disabled, 0/1 - template <> - struct ArgumentTraits - { - typedef bool type; - static bool const singleToken = true; - - static void parse(ParseCommandInfo::TokensRange const & tokens, bool & out); - static std::string description(); - static std::string str(bool value); - }; - - template <> - struct ReturnValueTraits - { - typedef bool type; - - static void format(bool value, std::ostream & os); - }; - - template <> - struct ArgumentTraits - { - typedef std::string type; - static bool const singleToken = true; - - static void parse(ParseCommandInfo::TokensRange const & tokens, std::string & out); - static std::string description(); - static std::string str(std::string const & value); - }; - -#endif - - /** \brief Format boolean value as \c true / \c false */ - void formatTrueFalse(bool value, std::ostream & os); - - /** \brief Format boolean value as \c yes / \c no */ - void formatYesNo(bool value, std::ostream & os); - - /** \brief Format boolean value as \c enabled / \c disabled */ - void formatEnabledDisabled(bool value, std::ostream & os); - - /** \brief Format boolean value as \c on / \c off */ - void formatOnOff(bool value, std::ostream & os); - - /** \brief Format boolean value as \c 1 / \c 0 */ - void formatOneZero(bool value, std::ostream & os); /** \brief Register enum type for argument parsing @@ -246,73 +199,65 @@ namespace console { # define SENF_CONSOLE_REGISTER_ENUM_MEMBER(Class, Type, Values) \ SENF_CONSOLE_REGISTER_ENUM_(Class::, Type, Values) - /** \brief Bit-mask flag argument type - senf::console::FlagCollection supplies a special argument type for use in registering - console commands. This argument type is used to represent a bit-mask of single flags. + /** \brief Format boolean value as \c true / \c false */ + void formatTrueFalse(bool value, std::ostream & os); - \code - // Function taking a flags argument - void func(unsigned flags); - - // Enum containing all the possible flag values - enum MyFlags { Foo = 1, - Bar = 2, - Baz = 4, - Doo = 8 }; - SENF_CONSOLE_REGISTER_ENUM(MyFlags, (Foo)(Bar)(Baz)(Boo)); - - // Register the function with a FlagCollection argument type - consoleDir.add("func", boost::function)>(&func)); - \endcode + /** \brief Format boolean value as \c yes / \c no */ + void formatYesNo(bool value, std::ostream & os); - To use the FlagCollection class - \li you need a function which takes a bit-mask of flags as argument - \li you define and register an enum with all possible flag values - \li you register the function with a FlagCollection argument type using \c boost::function - for the conversion. This is also possible for return values. - - The nice thing is, that \c boot::function supports compatible argument types and does - automatic type conversion. Since a FlagCollection is convertible to and from unsigned long, - this conversion will work. - - After registering this function, you can call it with a collection of flags as argument - -
-        console:/$ help func
-        Usage:
-            func arg11:MyFlags
-        console:/$ func Foo
-        console:/$ func (Foo Boo)
-        
- */ - template - struct FlagCollection + /** \brief Format boolean value as \c enabled / \c disabled */ + void formatEnabledDisabled(bool value, std::ostream & os); + + /** \brief Format boolean value as \c on / \c off */ + void formatOnOff(bool value, std::ostream & os); + + /** \brief Format boolean value as \c 1 / \c 0 */ + void formatOneZero(bool value, std::ostream & os); + + +#ifndef DOXYGEN + + // Parse bool: true/false, yes/no, enabled/disabled, 0/1 + template <> + struct ArgumentTraits { - operator unsigned long() const { return value; } - FlagCollection() : value (0) {} - FlagCollection(unsigned long value_) : value (value_) {} - FlagCollection(Enum value_) : value (value_) {} - unsigned long value; + typedef bool type; + static bool const singleToken = true; + + static void parse(ParseCommandInfo::TokensRange const & tokens, bool & out); + static std::string description(); + static std::string str(bool value); }; - template - struct ArgumentTraits< FlagCollection > + template <> + struct ReturnValueTraits { - typedef FlagCollection type; - static bool const singleToken = false; - static void parse(ParseCommandInfo::TokensRange const & tokens, type & out); - static std::string description(); - static std::string str(type const & value); + typedef bool type; + + static void format(bool value, std::ostream & os); }; - template - struct ReturnValueTraits< FlagCollection > + template <> + struct ArgumentTraits { - typedef FlagCollection type; - static void format(type const & value, std::ostream & os); + typedef std::string type; + static bool const singleToken = true; + + static void parse(ParseCommandInfo::TokensRange const & tokens, std::string & out); + static std::string description(); + static std::string str(std::string const & value); }; + template <> struct ArgumentTraits : public detail::CharArgumentTraits {}; + template <> struct ReturnValueTraits : public detail::CharReturnValueTraits {}; + template <> struct ArgumentTraits : public detail::CharArgumentTraits {}; + template <> struct ReturnValueTraits : public detail::CharReturnValueTraits {}; + template <> struct ArgumentTraits : public detail::CharArgumentTraits {}; + template <> struct ReturnValueTraits : public detail::CharReturnValueTraits {}; + +#endif + }} ///////////////////////////////hh.e//////////////////////////////////////// diff --git a/senf/Utils/Console/Traits.ih b/senf/Utils/Console/Traits.ih index 85213bb..c3d6127 100644 --- a/senf/Utils/Console/Traits.ih +++ b/senf/Utils/Console/Traits.ih @@ -28,19 +28,47 @@ // Custom includes #include +#include #include #include #include #include #include #include +#include #include ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { namespace console { + + template struct ArgumentTraits; + template struct ReturnValueTraits; + namespace detail { + + template + struct MatchingShortType + : public boost::mpl::if_c::is_signed,short,unsigned short> + {}; + + template + struct CharArgumentTraits + : public ArgumentTraits::type> + { + typedef ArgumentTraits::type> base; + typedef CharT type; + static void parse(ParseCommandInfo::TokensRange const & tokens, CharT & out); + static std::string description(); + }; + + template + struct CharReturnValueTraits + : public ReturnValueTraits::type> + { + typedef CharT type; + }; #ifndef DOXYGEN struct StringILess diff --git a/senf/Utils/Console/Traits.test.cc b/senf/Utils/Console/Traits.test.cc index b8d1d1f..85b9f35 100644 --- a/senf/Utils/Console/Traits.test.cc +++ b/senf/Utils/Console/Traits.test.cc @@ -28,6 +28,7 @@ // Custom includes #include "Traits.hh" +#include "Utility.hh" #include "ParsedCommand.hh" #include "Executor.hh" #include "Parse.hh" @@ -40,6 +41,12 @@ ///////////////////////////////cc.p//////////////////////////////////////// namespace { + char charTest(char value) { return value; } + signed char scharTest(signed char value) { return value; } + unsigned char ucharTest(unsigned char value) { return value; } + + bool boolTest(bool value) { return value; } + enum TestEnum { Foo=1, Bar=2, FooBar=4 }; SENF_CONSOLE_REGISTER_ENUM( TestEnum, (Foo)(Bar)(FooBar) ); @@ -50,11 +57,37 @@ namespace { static MemberEnum test (MemberEnum value) { return value; } }; SENF_CONSOLE_REGISTER_ENUM_MEMBER( TestClass, MemberEnum, (MemberFoo)(MemberBar) ); +} - bool boolTest(bool value) { return value; } +BOOST_AUTO_UNIT_TEST(charTraits) +{ + senf::console::Executor executor; + senf::console::CommandParser parser; + senf::console::ScopedDirectory<> dir; + senf::console::root().add("test", dir); + std::stringstream ss; + + dir.add("test",&charTest); + dir.add("stest",&scharTest); + dir.add("utest",&ucharTest); - senf::console::FlagCollection collectionTest( - senf::console::FlagCollection flags) { return flags; } + SENF_CHECK_NO_THROW( + parser.parse("test/test 10; test/test 20", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "10\n" "20\n" ); + ss.str(""); + + SENF_CHECK_NO_THROW( + parser.parse("test/stest 10; test/stest -20", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "10\n" "-20\n" ); + ss.str(""); + + SENF_CHECK_NO_THROW( + parser.parse("test/utest 10; test/utest 20", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "10\n" "20\n" ); + ss.str(""); } BOOST_AUTO_UNIT_TEST(boolTraits) @@ -162,35 +195,6 @@ BOOST_AUTO_UNIT_TEST(enumSupport) BOOST_CHECK_EQUAL( ss.str(), "Foo\n" ); } -BOOST_AUTO_UNIT_TEST(flagCollection) -{ - senf::console::Executor executor; - senf::console::CommandParser parser; - senf::console::ScopedDirectory<> dir; - senf::console::root().add("test", dir); - std::stringstream ss; - - dir.add("test",&collectionTest); - - ss.str(""); - SENF_CHECK_NO_THROW( - parser.parse("test/test foo", - boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); - BOOST_CHECK_EQUAL( ss.str(), "Foo\n" ); - - ss.str(""); - SENF_CHECK_NO_THROW( - parser.parse("test/test (foo bar)", - boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); - BOOST_CHECK_EQUAL( ss.str(), "(Foo Bar)\n" ); - - ss.str(""); - SENF_CHECK_NO_THROW( - parser.parse("test/test ()", - boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); - BOOST_CHECK_EQUAL( ss.str(), "()\n" ); -} - BOOST_AUTO_UNIT_TEST(singleToken) { BOOST_CHECK( senf::console::ArgumentTraits::singleToken ); diff --git a/senf/Utils/Console/Utility.ct b/senf/Utils/Console/Utility.ct index 771e36d..2f12892 100644 --- a/senf/Utils/Console/Utility.ct +++ b/senf/Utils/Console/Utility.ct @@ -32,6 +32,9 @@ #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::console::ArgumentTraits< senf::console::ValueRange > + template prefix_ void senf::console::ArgumentTraits< senf::console::ValueRange >:: parse(ParseCommandInfo::TokensRange const & tokens, type & out) @@ -69,6 +72,9 @@ str(type const & value) return ss.str(); } +/////////////////////////////////////////////////////////////////////////// +// senf::console::ReturnValueTraits< senf::console::ValueRange > + template prefix_ void senf::console::ReturnValueTraits< senf::console::ValueRange >:: format(type const & value, std::ostream & os) @@ -78,6 +84,57 @@ format(type const & value, std::ostream & os) os << ':' << senf::console::str(value.high); } +/////////////////////////////////////////////////////////////////////////// +// senf::console::ArgumentTraits< senf::console::FlagCollection > + +template +prefix_ void senf::console::ArgumentTraits< senf::console::FlagCollection >:: +parse(ParseCommandInfo::TokensRange const & tokens, type & out) +{ + CheckedArgumentIteratorWrapper arg (tokens); + out.value = 0; + while (arg) { + Enum v; + senf::console::parse( *(arg++), v); + out.value |= v; + } +} + +template +prefix_ std::string +senf::console::ArgumentTraits< senf::console::FlagCollection >::description() +{ + return ArgumentTraits::description(); +} + +template +prefix_ std::string +senf::console::ArgumentTraits< senf::console::FlagCollection >::str(type const & value) +{ + std::stringstream ss; + senf::console::format(value, ss); + return ss.str(); +} + +/////////////////////////////////////////////////////////////////////////// +// senf::console::ReturnValueTraits< senf::console::FlagCollection > + +template +prefix_ void senf::console::ReturnValueTraits< senf::console::FlagCollection >:: +format(type const & value, std::ostream & os) +{ + unsigned n (0); + std::stringstream ss; + unsigned long flag (1); + for (unsigned bit (0); bit(flag), ss); + } + } + os << (n != 1 ? "(" + ss.str() + ")" : ss.str()); +} + ///////////////////////////////ct.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Utils/Console/Utility.hh b/senf/Utils/Console/Utility.hh index beb8982..6ccc579 100644 --- a/senf/Utils/Console/Utility.hh +++ b/senf/Utils/Console/Utility.hh @@ -71,6 +71,77 @@ namespace console { #endif + /** \brief Bit-mask flag argument type + + senf::console::FlagCollection supplies a special argument type for use in registering + console commands. This argument type is used to represent a bit-mask of single flags. + + \code + // Function taking a flags argument + void func(unsigned flags); + + // Enum containing all the possible flag values + enum MyFlags { Foo = 1, + Bar = 2, + Baz = 4, + Doo = 8 }; + SENF_CONSOLE_REGISTER_ENUM(MyFlags, (Foo)(Bar)(Baz)(Boo)); + + // Register the function with a FlagCollection argument type + consoleDir.add("func", boost::function)>(&func)); + \endcode + + To use the FlagCollection class + \li you need a function which takes a bit-mask of flags as argument + \li you define and register an enum with all possible flag values + \li you register the function with a FlagCollection argument type using \c boost::function + for the conversion. This is also possible for return values. + + The nice thing is, that \c boot::function supports compatible argument types and does + automatic type conversion. Since a FlagCollection is convertible to and from unsigned long, + this conversion will work. + + After registering this function, you can call it with a collection of flags as argument + +
+        console:/$ help func
+        Usage:
+            func arg11:MyFlags
+        console:/$ func Foo
+        console:/$ func (Foo Boo)
+        
+ */ + template + struct FlagCollection + { + operator unsigned long() const { return value; } + FlagCollection() : value (0) {} + FlagCollection(unsigned long value_) : value (value_) {} + FlagCollection(Enum value_) : value (value_) {} + unsigned long value; + }; + +#ifndef DOXYGEN + + template + struct ArgumentTraits< FlagCollection > + { + typedef FlagCollection type; + static bool const singleToken = false; + static void parse(ParseCommandInfo::TokensRange const & tokens, type & out); + static std::string description(); + static std::string str(type const & value); + }; + + template + struct ReturnValueTraits< FlagCollection > + { + typedef FlagCollection type; + static void format(type const & value, std::ostream & os); + }; + +#endif + }} ///////////////////////////////hh.e//////////////////////////////////////// diff --git a/senf/Utils/Console/Utility.test.cc b/senf/Utils/Console/Utility.test.cc new file mode 100644 index 0000000..f5ff939 --- /dev/null +++ b/senf/Utils/Console/Utility.test.cc @@ -0,0 +1,94 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief Utility.test unit tests */ + +//#include "Utility.test.hh" +//#include "Utility.test.ih" + +// Custom includes +#include "Utility.hh" +#include "Traits.hh" +#include "ParsedCommand.hh" +#include "Executor.hh" +#include "Parse.hh" +#include "ScopedDirectory.hh" + +#include +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + + enum TestEnum { Foo=1, Bar=2, FooBar=4 }; + SENF_CONSOLE_REGISTER_ENUM( TestEnum, (Foo)(Bar)(FooBar) ); + + senf::console::FlagCollection collectionTest( + senf::console::FlagCollection flags) { return flags; } + +} + +BOOST_AUTO_UNIT_TEST(flagCollection) +{ + senf::console::Executor executor; + senf::console::CommandParser parser; + senf::console::ScopedDirectory<> dir; + senf::console::root().add("test", dir); + std::stringstream ss; + + dir.add("test",&collectionTest); + + ss.str(""); + SENF_CHECK_NO_THROW( + parser.parse("test/test foo", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "Foo\n" ); + + ss.str(""); + SENF_CHECK_NO_THROW( + parser.parse("test/test (foo bar)", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "(Foo Bar)\n" ); + + ss.str(""); + SENF_CHECK_NO_THROW( + parser.parse("test/test ()", + boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); + BOOST_CHECK_EQUAL( ss.str(), "()\n" ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Utils/TypeInfo.cc b/senf/Utils/TypeInfo.cc index bed2876..94d7cae 100644 --- a/senf/Utils/TypeInfo.cc +++ b/senf/Utils/TypeInfo.cc @@ -45,6 +45,16 @@ prefix_ std::string senf::prettyName(std::type_info const & type) return name; } +prefix_ std::string senf::prettyBaseName(std::type_info const & type) +{ + std::string name (prettyName(type)); + std::string::size_type e (name.find('<')); + if (e == std::string::npos) e = name.size(); + std::string::size_type b (name.rfind(':', e)); + if (b == std::string::npos) b = 0; else ++b; + return name.substr(b,e-b); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "TypeInfo.mpp" diff --git a/senf/Utils/TypeInfo.hh b/senf/Utils/TypeInfo.hh index e5e6998..6ce7311 100644 --- a/senf/Utils/TypeInfo.hh +++ b/senf/Utils/TypeInfo.hh @@ -37,15 +37,26 @@ namespace senf { /** \brief Try to return readable type for given type_info - This function will try to return a demangled type name for the - given type_info object. If the demangling fails, the possibly - mangled name (type->name()) will be returned. + This function will try to return a demangled type name for the given type_info object. If + the demangling fails, the possibly mangled name (type->name()) will be returned. \param[in] type type_info object \returns type name, possibly demangled */ std::string prettyName(std::type_info const & type); + /** \brief Try to return readable type name without namespace or template arguments + + This function will try to return a demangled type name for the given type_info object. If + the demangling fails, the possibly mangled name (type->name()) will be returned. The + namespace prefix and template arguments will be stripped. + + \param[in] type type_info object + \returns type name, possibly demangled and without namespace or template args + */ + + std::string prettyBaseName(std::type_info const & type); + } ///////////////////////////////hh.e////////////////////////////////////////