// senf::console::NodeCreateTraits<Object>::Creator
template <class Object>
-prefix_ typename senf::console::NodeCreateTraits<Object>::NodeType &
+prefix_ typename senf::console::NodeCreateTraits<Object>::result_type
senf::console::NodeCreateTraits<Object>::Creator::create(DirectoryNode & node,
std::string const & name,
Object const & ob)
}
template <class Object>
-prefix_ typename senf::console::NodeCreateTraits<Object>::NodeType &
+prefix_ typename senf::console::NodeCreateTraits<Object>::result_type
senf::console::DirectoryNode::add(std::string const & name, Object const & ob)
{
return NodeCreateTraits<Object>::Creator::create(*this, name, ob);
#include "../Utils/Exception.hh"
#include "../Utils/mpl.hh"
#include "../Utils/Logger/SenfLog.hh"
+#include "../Utils/type_traits.hh"
#include "Parse.hh"
//#include "Node.mpp"
* static_cast<DirectoryNode *>(0),
* static_cast<std::string const *>(0),
* static_cast<Object const *>(0),
- 0) ) result_type;
+ 0) ) base_type;
+ typedef typename senf::remove_cvref<base_type>::type value_type;
- typedef typename boost::remove_reference<result_type>::type NodeType;
+ typedef typename value_type::node_type NodeType;
+ typedef typename value_type::return_type result_type;
/// Internal
struct Creator {
- static NodeType & create(DirectoryNode & node, std::string const & name,
- Object const & ob);
+ static result_type create(DirectoryNode & node, std::string const & name,
+ Object const & ob);
};
};
typedef boost::iterator_range<ChildMap::const_iterator> ChildrenRange;
typedef ChildMap::const_iterator child_iterator;
+ typedef DirectoryNode node_type;
+ typedef DirectoryNode & return_type;
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///\{
\a name is empty, it is set to 'unnamed'. */
template <class Object>
- typename NodeCreateTraits<Object>::NodeType & add (std::string const & name,
- Object const & ob);
+ typename NodeCreateTraits<Object>::result_type add (std::string const & name,
+ Object const & ob);
///< Generic child node factory
/**< This member is used to create a new child node of the
current directory. The type of node created depends on
typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
+ typedef SimpleCommandNode node_type;
+ typedef SimpleCommandNode & return_type;
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///\{
typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
+ typedef OverloadedCommandNode node_type;
+ typedef OverloadedCommandNode & return_type;
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
doc_ = d;
}
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedCommandAttributorBase
+
+prefix_ senf::console::OverloadedCommandNode &
+senf::console::ParsedCommandAttributorBase::node()
+ const
+{
+ return overload_.node();
+}
+
+prefix_ senf::console::ParsedCommandAttributorBase::operator OverloadedCommandNode &()
+ const
+{
+ return node();
+}
+
+prefix_ senf::console::ParsedCommandAttributorBase::
+ParsedCommandAttributorBase(ParsedCommandOverloadBase & overload, unsigned index)
+ : overload_ (overload), index_ (index)
+{}
+
+prefix_ void senf::console::ParsedCommandAttributorBase::argName(std::string const & name)
+ const
+{
+ overload().arg(index_).name = name;
+}
+
+prefix_ void senf::console::ParsedCommandAttributorBase::argDoc(std::string const & doc)
+ const
+{
+ overload().arg(index_).doc = doc;
+}
+
+prefix_ senf::console::ParsedCommandOverloadBase &
+senf::console::ParsedCommandAttributorBase::overload()
+ const
+{
+ return overload_;
+}
+
+prefix_ void senf::console::ParsedCommandAttributorBase::overloadDoc(std::string const & doc)
+ const
+{
+ overload().doc(doc);
+}
+
+prefix_ void senf::console::ParsedCommandAttributorBase::nodeDoc(std::string const & doc)
+ const
+{
+ node().doc(doc);
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
#include BOOST_PP_ITERATE()
///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedCommandAttributorBase
+
+template <class Type>
+prefix_ void senf::console::ParsedCommandAttributorBase::defaultValue(Type const & value)
+ const
+{
+ overload().arg<Type>(index_).defaultValue = value;
+ overload().arg(index_).hasDefault = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedCommandAttributor<Overload>
+
+template <class Overload>
+prefix_ Overload & senf::console::ParsedCommandAttributor<Overload>::overload()
+ const
+{
+ return static_cast<Overload &>(ParsedCommandAttributorBase::overload());
+}
+
+template <class Overload>
+prefix_
+senf::console::ParsedCommandAttributor<Overload>::ParsedCommandAttributor(Overload & overload,
+ unsigned index)
+ : ParsedCommandAttributorBase (overload, index)
+{}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedAttributeAttributorBase<Overload,Self>
+
+template <class Overload, class Self>
+prefix_ Self
+senf::console::ParsedAttributeAttributorBase<Overload,Self>::doc(std::string const & doc)
+ const
+{
+ this->ParsedCommandAttributorBase::nodeDoc(doc);
+ return static_cast<Self const &>(*this);
+}
+
+template <class Overload, class Self>
+prefix_ Self senf::console::ParsedAttributeAttributorBase<Overload,Self>::
+overloadDoc(std::string const & doc)
+ const
+{
+ this->ParsedCommandAttributorBase::overloadDoc(doc);
+ return static_cast<Self const &>(*this);
+}
+
+template <class Overload, class Self>
+prefix_
+senf::console::ParsedAttributeAttributorBase<Overload,Self>::
+ParsedAttributeAttributorBase(Overload & overload, unsigned index)
+ : ParsedCommandAttributor<Overload> (overload, index)
+{}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedAttributeAttributor<Overload,index,flag>
+
+template <class Overload, unsigned index, bool flag>
+prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
+ std::string const & doc)
+ const
+{
+ this->argName(name);
+ this->argDoc(doc);
+ return next();
+}
+
+template <class Overload, unsigned index, bool flag>
+prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
+ std::string const & doc,
+ value_type const & value)
+ const
+{
+ this->argName(name);
+ this->argDoc(doc);
+ defaultValue(value);
+ return next();
+}
+
+template <class Overload, unsigned index, bool flag>
+prefix_
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::
+ParsedAttributeAttributor(Overload & overload)
+ : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
+{}
+
+template <class Overload, unsigned index, bool flag>
+prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::next()
+ const
+{
+ return ParsedAttributeAttributor<Overload, index+1>(this->overload());
+}
+
+template <class Overload, unsigned index, bool flag>
+prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
+defaultValue(value_type const & value)
+ const
+{
+ ParsedCommandAttributorBase::defaultValue<arg_type>(value);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParsedAttributeAttributor<Overload, index, false>
+
+template <class Overload, unsigned index>
+prefix_
+senf::console::ParsedAttributeAttributor<Overload, index, false>::
+ParsedAttributeAttributor(Overload & overload)
+ : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
+{}
+
+///////////////////////////////////////////////////////////////////////////
// namespace members
namespace {
}
template <class Function>
-prefix_ senf::console::ParsedCommandOverload<
- typename senf::console::detail::ParsedCommandTraits<Function>::traits> &
+prefix_ senf::console::ParsedAttributeAttributor<
+ senf::console::ParsedCommandOverload<
+ typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
Function fn, int)
{
? dynamic_cast<OverloadedCommandNode &>(node(name))
: node.add(name, OverloadedCommandNode::create()) );
- typedef senf::console::detail::ParsedCommandTraits<Function> CmdTraits;
+ typedef detail::ParsedCommandTraits<Function> CmdTraits;
+ typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
+ typedef ParsedAttributeAttributor<Overload> Attributor;
- return cmdNode.add( CreateParsedCommandOverload<
- typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) );
+ return Attributor(
+ cmdNode.add( CreateParsedCommandOverload<
+ typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) ) );
}
template <class Owner, class Function>
-prefix_ senf::console::ParsedCommandOverload<
- typename senf::console::detail::ParsedCommandTraits<Function>::traits> &
+prefix_ senf::console::ParsedAttributeAttributor<
+ senf::console::ParsedCommandOverload<
+ typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
senf::console::
senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
Function fn, int,
? dynamic_cast<OverloadedCommandNode &>(node(name))
: node.add(name, OverloadedCommandNode::create()) );
- typedef senf::console::detail::ParsedCommandTraits<Function> CmdTraits;
+ typedef detail::ParsedCommandTraits<Function> CmdTraits;
+ typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
+ typedef ParsedAttributeAttributor<Overload> Attributor;
- return cmdNode.add( CreateParsedCommandOverload<
- typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
- senf::membind(fn,&owner)) );
+ return Attributor(
+ cmdNode.add( CreateParsedCommandOverload<
+ typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
+ senf::membind(fn,&owner)) ) );
}
///////////////////////////////cti.e///////////////////////////////////////
1))
# include BOOST_PP_ITERATE()
+ class ParsedCommandAttributorBase
+ {
+ public:
+ OverloadedCommandNode & node() const;
+ operator OverloadedCommandNode & () const;
+
+ protected:
+ ParsedCommandAttributorBase(ParsedCommandOverloadBase & overload, unsigned index);
+
+ void argName(std::string const & name) const;
+ void argDoc(std::string const & doc) const;
+ template <class Type> void defaultValue(Type const & value) const;
+
+ ParsedCommandOverloadBase & overload() const;
+ void overloadDoc(std::string const & doc) const;
+
+ void nodeDoc(std::string const & doc) const;
+
+ private:
+ ParsedCommandOverloadBase & overload_;
+ unsigned index_;
+ };
+
+ template <class Overload>
+ class ParsedCommandAttributor
+ : public ParsedCommandAttributorBase
+ {
+ public:
+ Overload & overload() const;
+
+ protected:
+ ParsedCommandAttributor(Overload & overload, unsigned index);
+
+ private:
+ };
+
+ template <class Overload, class Self>
+ class ParsedAttributeAttributorBase
+ : public ParsedCommandAttributor<Overload>
+ {
+ public:
+ Self doc(std::string const & doc) const;
+ Self overloadDoc(std::string const & doc) const;
+
+ protected:
+ ParsedAttributeAttributorBase(Overload & overload, unsigned index);
+
+ private:
+ };
+
+ template <class Overload, unsigned index=0, bool flag=(index < unsigned(Overload::traits::arity))>
+ class ParsedAttributeAttributor
+ : public ParsedAttributeAttributorBase< Overload,
+ ParsedAttributeAttributor<Overload, index, flag> >
+ {
+ public:
+ typedef typename senf::function_traits_arg_type<
+ typename Overload::traits, int(index) >::type arg_type;
+ typedef typename senf::remove_cvref< arg_type >::type value_type;
+
+ typedef OverloadedCommandNode node_type;
+ typedef ParsedAttributeAttributor return_type;
+
+ ParsedAttributeAttributor<Overload, index+1> arg(std::string const & name = "",
+ std::string const & doc = "") const;
+ ParsedAttributeAttributor<Overload, index+1> arg(std::string const & name,
+ std::string const & doc,
+ value_type const & value) const;
+
+ private:
+ explicit ParsedAttributeAttributor(Overload & overload);
+
+ ParsedAttributeAttributor<Overload, index+1> next() const;
+
+ void defaultValue(value_type const & value) const;
+
+ template <class O, unsigned i, bool f>
+ friend class ParsedAttributeAttributor;
+
+ template <class Function>
+ friend ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
+ senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int);
+
+ template <class Owner, class Function>
+ friend ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
+ senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
+ Function fn, int,
+ typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+ };
+
+ template <class Overload, unsigned index>
+ class ParsedAttributeAttributor<Overload, index, false>
+ : public ParsedAttributeAttributorBase< Overload,
+ ParsedAttributeAttributor<Overload, index, false> >
+ {
+ public:
+ typedef OverloadedCommandNode node_type;
+ typedef ParsedAttributeAttributor return_type;
+
+ private:
+ explicit ParsedAttributeAttributor(Overload & overload);
+
+ template <class O, unsigned i, bool f>
+ friend class ParsedAttributeAttributor;
+
+ template <class Function>
+ friend ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
+ senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int);
+
+ template <class Owner, class Function>
+ friend ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
+ senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
+ Function fn, int,
+ typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+ };
+
#ifndef DOXYGEN
template <class Function>
- ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> &
+ ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int);
template <class Owner, class Function>
- ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> &
+ ParsedAttributeAttributor<
+ ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
Function fn, int,
typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TEMPLATE(senf::console::ParsedCommandOverload, (class,unsigned))
+BOOST_TYPEOF_REGISTER_TEMPLATE(senf::console::ParsedAttributeAttributor, (class, unsigned, bool))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function_traits, 1)
///////////////////////////////hh.e////////////////////////////////////////
mpp_TrailingArgTypes())> Function;
# define mpp_l(z,n,d) \
- typedef typename boost::remove_const< \
- typename boost::remove_reference< typename traits::mpp_ArgTypeN(n) >::type >::type \
- mpp_ArgTypeN(n);
+ typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
+ mpp_ArgTypeN(n);
BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
# undef mpp_l
{
std::stringstream ss;
- senf::console::ParsedCommandOverloadBase & c1 (dir.add("cb", &cb1));
- c1.doc(
- "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n"
- "pupa Sive res indifferenter. Captivo pa.");
- c1.arg(0).doc = "Bar didelfrump di desgorb. Nu widsoflar brimeldrgf.";
- c1.arg(1).name = "checkup";
- c1.arg(1).doc = "Florgel, dargel and durgel";
- c1.arg<double>(1).defaultValue = 2.1;
- c1.arg(1).hasDefault = true;
- senf::console::ParsedCommandOverloadBase & c5 (dir.add("cb", &cb5));
- c5.doc(
- "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
- "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
- "iam, in vos nam Custodi.");
+ senf::console::OverloadedCommandNode & cbNode ( dir.add("cb", &cb1)
+ .doc(
+ "Ops fortunate, ops me ut orgia vociferatio contumax per, rudo re loco emitto\n"
+ "intolerabiliter ita iugo. Subcribo gravo. Devenio luna fonticulus Castanea\n"
+ "horum fascino Os interpretor non ipse conjuratio hora, qui filius denuntio ait\n"
+ "sono te odium Anhelo. Dum Cedo audax celox alius una Agnosco hic, ibi retineo\n"
+ "lux sto ioco. Per Re dono. Copiose reus scitus jus diligens sis scapulare\n"
+ "Servitium transi.")
+ .overloadDoc(
+ "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n"
+ "pupa Sive res indifferenter. Captivo pa.")
+ .arg("", "Bar didelfrump di desgorb. Nu widsoflar brimeldrgf.")
+ .arg("checkup", "Florgel, dargel and durgel", 2.1) );
+
+ dir.add("cb", &cb5)
+ .overloadDoc(
+ "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
+ "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
+ "iam, in vos nam Custodi.");
+
+ (void) cbNode;
+
dir.add("cb", &cb2);
- static_cast<senf::console::OverloadedCommandNode&>(dir("cb")).doc(
- "Ops fortunate, ops me ut orgia vociferatio contumax per, rudo re loco emitto\n"
- "intolerabiliter ita iugo. Subcribo gravo. Devenio luna fonticulus Castanea\n"
- "horum fascino Os interpretor non ipse conjuratio hora, qui filius denuntio ait\n"
- "sono te odium Anhelo. Dum Cedo audax celox alius una Agnosco hic, ibi retineo\n"
- "lux sto ioco. Per Re dono. Copiose reus scitus jus diligens sis scapulare\n"
- "Servitium transi.");
+
parser.parse("test/cb 111 222.4; test/cb 222; test/cb foo; test/cb",
boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 ));
BOOST_CHECK_EQUAL( ss.str(), "333\n" "224\n" "Value: foo\n" "1.2\n" );
// senf::console::OwnerNodeCreateTraits<Owner,Object>::Creator
template <class Owner, class Object>
-prefix_ typename senf::console::OwnerNodeCreateTraits<Owner,Object>::NodeType &
+prefix_ typename senf::console::OwnerNodeCreateTraits<Owner,Object>::result_type
senf::console::OwnerNodeCreateTraits<Owner,Object>::Creator::create(DirectoryNode & node,
Owner & owner,
std::string const & name,
template <class Owner>
template <class Object>
-prefix_ typename senf::console::OwnerNodeCreateTraits<Owner, Object>::NodeType &
+prefix_ typename senf::console::OwnerNodeCreateTraits<Owner, Object>::result_type
senf::console::ScopedDirectory<Owner>::add(std::string const & name, Object const & ob)
{
return OwnerNodeCreateTraits<Owner, Object>::Creator::create(node(), *owner_, name, ob);
// senf::console::ScopedDirectory<void>
template <class Object>
-prefix_ typename senf::console::NodeCreateTraits<Object>::NodeType &
+prefix_ typename senf::console::NodeCreateTraits<Object>::result_type
senf::console::ScopedDirectory<void>::add(std::string const & name, Object const & ob)
{
return node().add(name, ob);
* static_cast<Owner *>(0),
* static_cast<std::string const *>(0),
* static_cast<Object const *>(0),
- * static_cast<int *>(0)) ) result_type;
+ * static_cast<int *>(0)) ) base_type;
+ typedef typename senf::remove_cvref<base_type>::type value_type;
- typedef typename boost::remove_reference<result_type>::type NodeType;
+ typedef typename value_type::node_type NodeType;
+ typedef typename value_type::return_type result_type;
/// Internal
struct Creator {
- static NodeType & create(DirectoryNode & node, Owner & owner,
+ static result_type create(DirectoryNode & node, Owner & owner,
std::string const & name, Object const & ob);
};
};
///////////////////////////////////////////////////////////////////////////
template <class Object>
- typename OwnerNodeCreateTraits<Owner, Object>::NodeType & add(std::string const & name,
- Object const & ob);
+ typename OwnerNodeCreateTraits<Owner, Object>::result_type add(std::string const & name,
+ Object const & ob);
///< Create new child node
/**< Adds a new child node to the (proxied)
DirectoryNode. How the node is added is configured
{
public:
template <class Object>
- typename NodeCreateTraits<Object>::NodeType & add(std::string const & name,
- Object const & ob);
+ typename NodeCreateTraits<Object>::result_type add(std::string const & name,
+ Object const & ob);
};
#ifndef DOXYGEN
The Utilities Library is a collection of independent utilities.
- \section basic_helpers C++ Language helpers and simple library extensions
+ \section basic_helpers C++ Language helpers and library extensions
<table class="listing">
<tr><td>\ref membind</td><td>a simple <a
tasks</td></tr>
<tr><td>\ref senfpp</td><td>Extensions to the Boost.Preprocessor library</td></tr>
+
+ <tr><td>\ref typetraits</td><td>Extensions to the Boost.TypeTraits library</td></tr>
</table>
- \section basic_mixins Basic mixin classes
+ \section basic_mixins Mixin classes
<table class="listing">
<tr><td>\ref intrusive_refcount</td><td>mixin to simplify writing classes for use with <a
to mark missing arguments
\note Don't use this as an empty base class. We may add some informative members to this.
+ \ingroup senfmpl
*/
struct nil {};
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
#include <boost/bind.hpp>
+#include "../config.hh"
#include "type_traits.mpp"
///////////////////////////////hh.p////////////////////////////////////////
-namespace senf {
+namespace senf
+{
- template <class Traits, unsigned arity=Traits::arity>
+ /** \defgroup typetraits Type traits
+ */
+
+ ///\addtogroup typetraits
+ ///\{
+
+ /** \brief Strip first parameter from function traits
+
+ This meta-function will remove the first argument from \a Traits. The return value is a new
+ function trait with one less argument.
+
+ If the function described in \a Traits does not take any arguments, it is returned
+ unchanged.
+
+ \code
+ typedef boost::function_traits<void (int, double)> traits
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::function_traits_remove_arg< traits >::type,
+ boost::function_traits<void (double)>
+ >::value ));
+ \endcode
+
+ \tparam Traits \c boost::function_traits instantiation
+ */
+ template < class Traits, unsigned arity = Traits::arity >
struct function_traits_remove_arg {};
- template <class MemberPointer>
- struct remove_member_pointer
+ /** \brief Get argument type from function traits
+
+ function_traits_arg<Traits, index> will return the type of the \a index-th argument from \a
+ Traits. If the function has no argument at that index, \c void is returned
+
+ \code
+ typedef boost::function_traits<void (int, double)> traits;
+ BOOST_STATIC_ASSERT(( boost:is_same<
+ senf::function_traits_arg_type< traits, 0 >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::function_traits_arg_type< traits, 2 >::type,
+ void
+ >::value ));
+ \endcode
+
+ \tparam Traits \c boost::function_traits instantiation
+ \tparam index 0 based argument index
+ */
+ template < class Traits, int index, bool flag = (index < Traits::arity) >
+ struct function_traits_arg_type {};
+
+#ifndef DOXYGEN
+
+ template < class Traits, int index >
+ struct function_traits_arg_type <Traits, index, false >
+ {
+ typedef void type;
+ };
+
+#endif
+
+ /** \brief Remove member pointer from type
+
+ This meta function will remove any type of member pointer from it's argument. Other types
+ will be returned unchanged.
+
+ \code
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_member_pointer< int (Class::*) >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_member_pointer< void (Class::*)(int) >::type,
+ void (int)
+ >::value ));
+ \endcode
+
+ \tparam MemberPointer type to return member pointer from
+ */
+ template < class MemberPointer > struct remove_member_pointer
{
typedef MemberPointer type;
};
- template <class C, class T>
- struct remove_member_pointer<T (C::*)>
+#ifndef DOXYGEN
+
+ template < class C, class T > struct remove_member_pointer <T (C::*) >
{
typedef T type;
};
- template <class MemberPointer>
- struct member_class
+#endif
+
+ /** \brief Get class of a member pointer
+
+ Returns the class, an arbitrary member pointer belongs to. If the argument is not a member
+ pointer, void is returned.
+
+ \code
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::member_class< int (Class::*) >::type,
+ Class
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_Same<
+ senf::member_class< int * >::type,
+ void
+ >::value ));
+ \endcode
+
+ \tparam MemberPointer Type to get the member pointer class from
+ */
+ template < class MemberPointer > struct member_class
{
typedef void type;
};
+
+#ifndef DOXYGEN
- template <class C, class T>
- struct member_class<T (C::*)>
+ template < class C, class T > struct member_class <T (C::*) >
{
typedef C type;
};
- template <class T>
+#endif
+
+ /** \brief Remove any type of pointer from type
+
+ This meta function will remove a plain or member pointer from the given type. If \a T is
+ neither a member pointer nor an ordinary pointer, \a T will be returned unchanged.
+
+ \code
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer< int (Class::*) >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer< void (Class::*)(int) >::type,
+ void (int) > );
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer < int (*)() >::type,
+ int (
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer < int >::type,
+ int
+ >::value ));
+ \endcode
+
+ \tparam T type to remove member pointer from
+ */
+ template < class T >
struct remove_any_pointer
- : public remove_member_pointer<typename boost::remove_pointer<T>::type>
+ : public remove_member_pointer < typename boost::remove_pointer < T >::type >
{};
- template <class T>
+ /** \brief Test object if it is a function or member-function (pointer)
+
+ is_any_function will inherit from \c boost::true_type, when \a T is a function type,
+ function pointer type or a member function pointer type. Otherwise, it will inherit from \c
+ boost::false_type.
+
+ \code
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void () >::value ));
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void (*)(int) >::value ));
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void (Class::*)() >::value ));
+ BOOST_STATIC_ASSERT(( ! senf::is_any_function< int * >::value ));
+ \endcode
+
+ \tparam T type to test
+ */
+ template < class T >
struct is_any_function
- : public boost::is_function<typename senf::remove_any_pointer<T>::type>
+ : public boost::is_function < typename senf::remove_any_pointer < T >::type >
{};
-# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, 10, \
- SENF_ABSOLUTE_INCLUDE_PATH(Utils/type_traits.mpp), \
+ /** \brief Remove reference and CV qualification from type
+
+ remove_cvref will remove all the 'ornaments' from a type as typically used to pass
+ arguments: references and any CV spec. It will thus convert a typical argument type into
+ it's basic type.
+
+ \code
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_cvref<int const &>::type,
+ int
+ >::value ));
+ \endcode
+ */
+ template < class T >
+ struct remove_cvref
+ : public boost::remove_cv< typename boost::remove_reference<T>::type >
+ {};
+
+ ///}
+
+#ifndef DOXYGEN
+
+# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, 10, \
+ SENF_ABSOLUTE_INCLUDE_PATH(Utils/type_traits.mpp), \
1))
# include BOOST_PP_ITERATE()
+#endif
+
}
///////////////////////////////hh.e////////////////////////////////////////
//#include "type_traits.ct"
//#include "type_traits.cti"
#endif
-
\f
+
// Local Variables:
// mode: c++
// fill-column: 100
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
// ///////////////////////////mpp.p////////////////////////////////////////
#elif BOOST_PP_IS_ITERATING // ////////////////////////////////////////////
typedef C type;
};
+template <class Traits>
+struct function_traits_arg_type<Traits, BOOST_PP_ITERATION(), true>
+{
+ typedef typename Traits::mpp_Arg(BOOST_PP_ITERATION()) type;
+};
+
// ////////////////////////////////////////////////////////////////////////
#endif // /////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief type_traits.test unit tests */
+
+//#include "type_traits.test.hh"
+//#include "type_traits.test.ih"
+
+// Custom includes
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include "type_traits.hh"
+
+#include "../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+ struct Class {};
+}
+
+BOOST_AUTO_UNIT_TEST(typeTraits)
+{
+ typedef boost::function_traits<void (int, double)> traits;
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::function_traits_remove_arg< traits >::type,
+ boost::function_traits<void (double)>
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::function_traits_arg_type< traits, 0 >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::function_traits_arg_type< traits, 2 >::type,
+ void
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_member_pointer< int (Class::*) >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_member_pointer< void (Class::*)(int) >::type,
+ void (int)
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::member_class< int (Class::*) >::type,
+ Class
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::member_class< int * >::type,
+ void
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer< int (Class::*) >::type,
+ int
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer< void (Class::*)(int) >::type,
+ void (int)
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer < int (*)() >::type,
+ int ()
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_any_pointer < int >::type,
+ int
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void () >::value ));
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void (*)(int) >::value ));
+ BOOST_STATIC_ASSERT(( senf::is_any_function< void (Class::*)() >::value ));
+ BOOST_STATIC_ASSERT(( ! senf::is_any_function< int * >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::is_same<
+ senf::remove_cvref<int const &>::type,
+ int
+ >::value ));
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// 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: