From: g0dil Date: Wed, 9 Apr 2008 08:56:05 +0000 (+0000) Subject: Utils: Fix intrusive_refcount for const objects X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=5209d7573f53f4b32730833af00668f5c0e56147;p=senf.git Utils: Fix intrusive_refcount for const objects Console: Fix parsing of commands in the presence of default arguments Console: Generate automatic online help for automatically parsed commands git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@794 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/OverloadedCommand.cc b/Console/OverloadedCommand.cc index 5edbd20..47a08dc 100644 --- a/Console/OverloadedCommand.cc +++ b/Console/OverloadedCommand.cc @@ -35,15 +35,118 @@ /////////////////////////////////////////////////////////////////////////// // senf::console::OverloadedCommandNode +/////////////////////////////////////////////////////////////////////////// +// So soll die doku aussehen: +// +// Usage: +// 1- foo arg1:int arg2:double +// 2- foo arg3:string +// 3- foo +// +// With: +// arg1 - arg1-doc +// arg2 - arg2-doc +// default: 1.23 +// arg3 - arg3-doc +// +// Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj +// sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd +// Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj +// sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd +// Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj +// sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd +// +// Variant 1: +// Variant 1 doc la;ksjf lkj sdlkfj lkjekj sdflkj ekljsdlkfj wlej +// slkj dkj sldkfj lwekljsdf skldjf lskjdf l jsd +// +// Variant 2: +// Variant 2 doc lskdfj lwkej lksjdflksjf +// +// Variatn 3: +// Variant 3 doc slkjflw ekj lskdfj lskdjf laksdj flksj elkj aldskjf lwkejlksdj +// ldkfaj wlekj slkdfj lskdjf lwkejlkasdjf + prefix_ void senf::console::OverloadedCommandNode::v_help(std::ostream & os) const { - os << doc_; - Overloads::const_iterator i (overloads_.begin()); - Overloads::const_iterator const i_end (overloads_.end()); - for (; i != i_end; ++i) { - os << "\n\n"; - (*i)->help(os); + typedef std::vector ArgumentDocs; + ArgumentDocs argumentDocs; + bool haveDocumentedArg (false); + + os << "Usage:\n"; + { + Overloads::const_iterator i (overloads_.begin()); + Overloads::const_iterator const i_end (overloads_.end()); + unsigned index (1); + for (; i != i_end; ++i, ++index) { + os << " " << index << "- " << name(); + for (unsigned j (0); j < (*i)->numArguments(); ++j) { + ArgumentDoc arg; + (*i)->argumentDoc(j, arg); + + os << ' '; + if (! arg.defaultValue.empty()) + os << '['; + if (! arg.name.empty()) os << arg.name; + if (! arg.type.empty()) os << ':' << arg.type; + if (arg.name.empty() && arg.type.empty()) os << "..."; + if (! arg.defaultValue.empty()) + os << ']'; + + if (! arg.name.empty()) { + ArgumentDocs::iterator k (argumentDocs.begin()); + ArgumentDocs::iterator const k_end (argumentDocs.end()); + for (; k != k_end; ++k) + if (k->name == arg.name && k->defaultValue == arg.defaultValue) { + if (! arg.doc.empty() && k->doc.empty()) { + k->doc == arg.doc; + haveDocumentedArg = true; + } + break; + } + if (k == k_end) { + argumentDocs.push_back(arg); + if (! arg.doc.empty()) + haveDocumentedArg = true; + } + } + } + os << '\n'; + } + } + + if (haveDocumentedArg) { + os << "\n" "With:\n"; + ArgumentDocs::const_iterator i (argumentDocs.begin()); + ArgumentDocs::const_iterator const i_end (argumentDocs.end()); + for (; i != i_end; ++i) { + if (! i->doc.empty()) { + os << " " + << i->name + << std::string(i->name.length()<8 ? 8-i->name.length() : 0, ' ') + << " " + << i->doc + << '\n'; + if (! i->defaultValue.empty()) + os << " default: " << i->defaultValue << '\n'; + } + } + } + + if (! doc_.empty()) + os << "\n" << doc_ << "\n"; + + { + Overloads::const_iterator i (overloads_.begin()); + Overloads::const_iterator const i_end (overloads_.end()); + unsigned index (1); + for (; i != i_end; ++i, ++index) { + std::string overloadDoc ((*i)->doc()); + if (! overloadDoc.empty()) + os << "\n" << "Variant " << index << ":\n" + << overloadDoc << "\n"; + } } } @@ -69,10 +172,20 @@ prefix_ void senf::console::OverloadedCommandNode::v_execute(std::ostream & outp /////////////////////////////////////////////////////////////////////////// // senf::console::SimpleCommandOverload -prefix_ void senf::console::SimpleCommandOverload::v_help(std::ostream & os) +prefix_ unsigned senf::console::SimpleCommandOverload::v_numArguments() + const +{ + return 1; +} + +prefix_ void senf::console::SimpleCommandOverload::v_argumentDoc(unsigned index, ArgumentDoc & doc) + const +{} + +prefix_ std::string senf::console::SimpleCommandOverload::v_doc() const { - os << doc_; + return doc_; } prefix_ void senf::console::SimpleCommandOverload::v_execute(std::ostream & os, diff --git a/Console/OverloadedCommand.cci b/Console/OverloadedCommand.cci index 6fc076d..4892e53 100644 --- a/Console/OverloadedCommand.cci +++ b/Console/OverloadedCommand.cci @@ -48,17 +48,37 @@ prefix_ void senf::console::CommandOverload::operator()(std::ostream & os, execute(os, command); } -prefix_ void senf::console::CommandOverload::help(std::ostream & os) +prefix_ unsigned senf::console::CommandOverload::numArguments() + const +{ + return v_numArguments(); +} + +prefix_ void senf::console::CommandOverload::argumentDoc(unsigned index, ArgumentDoc & doc) + const +{ + return v_argumentDoc(index,doc); +} + +prefix_ std::string senf::console::CommandOverload::doc() + const { - v_help(os); + return v_doc(); } prefix_ senf::console::OverloadedCommandNode & senf::console::CommandOverload::node() + const { SENF_ASSERT( node_ ); return *node_; } +prefix_ unsigned senf::console::CommandOverload::overloadIndex() + const +{ + return node().overloadIndex(*this); +} + prefix_ senf::console::CommandOverload::CommandOverload() : node_(0) {} @@ -89,6 +109,13 @@ senf::console::OverloadedCommandNode::doc(std::string const & doc) return *this; } +prefix_ unsigned +senf::console::OverloadedCommandNode::overloadIndex(CommandOverload const & overload) +{ + return find(overloads_.begin(), overloads_.end(), CommandOverload::cptr(&overload)) + - overloads_.begin() + 1; +} + prefix_ senf::console::OverloadedCommandNode::OverloadedCommandNode() {} diff --git a/Console/OverloadedCommand.cti b/Console/OverloadedCommand.cti index d4d6df8..b5e7a75 100644 --- a/Console/OverloadedCommand.cti +++ b/Console/OverloadedCommand.cti @@ -38,6 +38,7 @@ prefix_ Command & senf::console::OverloadedCommandNode::add(boost::intrusive_ptr overload) { overloads_.push_back(overload); + overload->node_ = this; return *overload; } diff --git a/Console/OverloadedCommand.hh b/Console/OverloadedCommand.hh index a967120..48b1097 100644 --- a/Console/OverloadedCommand.hh +++ b/Console/OverloadedCommand.hh @@ -39,6 +39,13 @@ namespace console { class OverloadedCommandNode; + struct ArgumentDoc { + std::string name; + std::string type; + std::string defaultValue; + std::string doc; + }; + /** \brief Base class for command overload of OverloadedCommandNode This class is the base class of the commands which may be added to an @@ -52,6 +59,7 @@ namespace console { // Types typedef boost::intrusive_ptr ptr; + typedef boost::intrusive_ptr cptr; /////////////////////////////////////////////////////////////////////////// @@ -68,12 +76,15 @@ namespace console { /**< If the \a arguments are not acceptable for this overload, a SyntaxErrorException must be thrown. Same as execute() */ - - void help(std::ostream & os); ///< Provide help for this specific overload - - OverloadedCommandNode & node(); ///< Access owning node + + unsigned numArguments() const; + void argumentDoc(unsigned index, ArgumentDoc & doc) const; + std::string doc() const; + + OverloadedCommandNode & node() const; ///< Access owning node /**< \pre The command \e must have been added to an OverloadedCommandNode. */ + unsigned overloadIndex() const; protected: CommandOverload(); @@ -81,7 +92,9 @@ namespace console { #ifndef DOXYGEN private: #endif - virtual void v_help(std::ostream & os) const = 0; + virtual unsigned v_numArguments() const = 0; + virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const = 0; + virtual std::string v_doc() const = 0; virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const = 0; private: @@ -143,6 +156,8 @@ namespace console { OverloadedCommandNode & doc(std::string const & doc); ///< Assign global help for all overloads + unsigned overloadIndex(CommandOverload const & overload); + protected: private: @@ -192,7 +207,9 @@ namespace console { private: SimpleCommandOverload(Function fn); - virtual void v_help(std::ostream & os) const; + virtual unsigned v_numArguments() const; + virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const; + virtual std::string v_doc() const; virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const; Function fn_; diff --git a/Console/OverloadedCommand.test.cc b/Console/OverloadedCommand.test.cc index 7459086..ad68f57 100644 --- a/Console/OverloadedCommand.test.cc +++ b/Console/OverloadedCommand.test.cc @@ -78,7 +78,22 @@ BOOST_AUTO_UNIT_TEST(overladedCommand) { std::stringstream ss; cmd.help(ss); - BOOST_CHECK_EQUAL( ss.str(), "cmd\n\nfn1\n\nfn2\n\nfn3" ); + BOOST_CHECK_EQUAL( ss.str(), + "Usage:\n" + " 1- overload ...\n" + " 2- overload ...\n" + " 3- overload ...\n" + "\n" + "cmd\n" + "\n" + "Variant 1:\n" + "fn1\n" + "\n" + "Variant 2:\n" + "fn2\n" + "\n" + "Variant 3:\n" + "fn3\n" ); } cmd.unlink(); diff --git a/Console/ParseParameter.cti b/Console/ParseParameter.cti index a36a08c..a88d7f3 100644 --- a/Console/ParseParameter.cti +++ b/Console/ParseParameter.cti @@ -54,6 +54,13 @@ prefix_ senf::console::detail::ParameterInfo::ParameterInfo() defaultValue () {} +template +prefix_ std::string senf::console::detail::ParameterInfo::defaultValueStr() + const +{ + return hasDefault ? ParameterTraits::dump(defaultValue) : ""; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::detail::ReturnValueTraits @@ -92,7 +99,15 @@ parse(ParseCommandInfo::TokensRange const & tokens, Type & out) template prefix_ std::string senf::console::detail::ParameterTraits::typeDescription() { - return prettyName(typeid(Type)); + std::string type (prettyName(typeid(Type))); + std::string::size_type i (type.rfind(':')); + return i == std::string::npos ? type : type.substr(i+1); +} + +template +prefix_ std::string senf::console::detail::ParameterTraits::dump(Type const & value) +{ + return boost::lexical_cast(value); } ///////////////////////////////cti.e/////////////////////////////////////// diff --git a/Console/ParseParameter.hh b/Console/ParseParameter.hh index 31ac63e..73a8fc6 100644 --- a/Console/ParseParameter.hh +++ b/Console/ParseParameter.hh @@ -48,8 +48,11 @@ namespace detail { std::string type; std::string name; bool hasDefault; + std::string doc; ParameterInfoBase(std::string const & type); + + virtual std::string defaultValueStr() const = 0; }; template @@ -62,6 +65,8 @@ namespace detail { ParameterInfo(); ParameterType defaultValue; + + virtual std::string defaultValueStr() const; }; template @@ -88,6 +93,7 @@ namespace detail { typedef Type type; static void parse(ParseCommandInfo::TokensRange const & tokens, Type & out); static std::string typeDescription(); + static std::string dump(Type const & value); }; }}} diff --git a/Console/ParsedCommand.cc b/Console/ParsedCommand.cc index 3a62096..3f27917 100644 --- a/Console/ParsedCommand.cc +++ b/Console/ParsedCommand.cc @@ -35,9 +35,31 @@ /////////////////////////////////////////////////////////////////////////// // senf::console::ParsedCommandOverloadBase -prefix_ void senf::console::ParsedCommandOverloadBase::v_help(std::ostream & os) +prefix_ unsigned senf::console::ParsedCommandOverloadBase::v_numArguments() const -{} +{ + return parameters_.size(); +} + +prefix_ void senf::console::ParsedCommandOverloadBase::v_argumentDoc(unsigned index, + ArgumentDoc & doc) + const +{ + BOOST_ASSERT( index < parameters_.size() ); + detail::ParameterInfoBase & arg (*parameters_[index]); + doc.name = arg.name.empty() + ? (boost::format("arg%d%d") % overloadIndex() % (index+1)).str() + : arg.name; + doc.type = arg.type; + doc.defaultValue = arg.defaultValueStr(); + doc.doc = arg.doc; +} + +prefix_ std::string senf::console::ParsedCommandOverloadBase::v_doc() + const +{ + return doc_; +} ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Console/ParsedCommand.cci b/Console/ParsedCommand.cci index 4d4fc29..94bbf32 100644 --- a/Console/ParsedCommand.cci +++ b/Console/ParsedCommand.cci @@ -44,6 +44,11 @@ senf::console::ParsedCommandOverloadBase::arg(unsigned n) return * parameters_[n]; } +prefix_ void senf::console::ParsedCommandOverloadBase::doc(std::string const & d) +{ + doc_ = d; +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Console/ParsedCommand.cti b/Console/ParsedCommand.cti index 9cdb279..60b7fde 100644 --- a/Console/ParsedCommand.cti +++ b/Console/ParsedCommand.cti @@ -27,6 +27,7 @@ // Custom includes #include "../Utils/membind.hh" +#include #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -39,7 +40,7 @@ prefix_ senf::console::detail::ParameterInfo & senf::console::ParsedCommandOverloadBase::arg(unsigned n) const { - return static_cast &>(arg(n)); + return dynamic_cast &>(arg(n)); } template diff --git a/Console/ParsedCommand.hh b/Console/ParsedCommand.hh index b2fca48..70f4203 100644 --- a/Console/ParsedCommand.hh +++ b/Console/ParsedCommand.hh @@ -51,20 +51,25 @@ namespace console { public: typedef boost::intrusive_ptr ptr; - protected: - ParsedCommandOverloadBase(); - detail::ParameterInfoBase & arg(unsigned n) const; template detail::ParameterInfo & arg(unsigned n) const; + void doc(std::string const & d); + + protected: + ParsedCommandOverloadBase(); + template void addParameter(); private: - virtual void v_help(std::ostream & os) const; + virtual unsigned v_numArguments() const; + virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const; + virtual std::string v_doc() const; typedef std::vector Parameters; Parameters parameters_; + std::string doc_; }; template diff --git a/Console/ParsedCommand.mpp b/Console/ParsedCommand.mpp index 57948c1..2aadffc 100644 --- a/Console/ParsedCommand.mpp +++ b/Console/ParsedCommand.mpp @@ -125,34 +125,19 @@ v_execute(std::ostream & os, ParseCommandInfo const & command) { if ( command.arguments().size() > BOOST_PP_ITERATION() || (command.arguments().size() < BOOST_PP_ITERATION() - && ! arg( BOOST_PP_ITERATION()-1 ).hasDefault) ) + && ! arg( command.arguments().size() ).hasDefault) ) throw SyntaxErrorException("invalid number of arguments"); - // First define local variables argN for the parameters. The variables are initialized to their - // default values -# define mpp_l(z,n,d) mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue); - BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) -# undef mpp_l - ParseCommandInfo::argument_iterator i (command.arguments().begin()); ParseCommandInfo::argument_iterator const i_end (command.arguments().end()); - // Now parse the arguments which are provided leaving the trailing arguments at their default - // value. We have already checked above, whether those default values are valid. Be aware, that - // the following cases do NOT have 'break' statements ! - - switch (BOOST_PP_ITERATION() - command.arguments().size()) { - # define mpp_l(z,n,d) \ - case n : \ + mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue); \ + if (i != i_end) \ detail::ParameterTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) # undef mpp_l - default : // This happens, if ALL arguments are defaulted - ; - } - // Now call the function binding the arguments to the values parsed above. callAndWrite is // specialized to ignore a 'void' return value but automatically write all other values to the // output stream. diff --git a/Console/ParsedCommand.test.cc b/Console/ParsedCommand.test.cc index 98a5584..5b90f2c 100644 --- a/Console/ParsedCommand.test.cc +++ b/Console/ParsedCommand.test.cc @@ -27,6 +27,7 @@ //#include "ParsedCommand.test.ih" // Custom includes +#include #include #include "ParsedCommand.hh" #include "Executor.hh" @@ -42,10 +43,10 @@ namespace { int cb1(int a, double b) { return int(a+b); } - double cb2() { return 1.2; } - void cb3(int) {} + double cb2(){ return 1.2; } + void cb3(int i) { } std::string cb4(std::ostream & os) { os << "text\n"; return "value"; } - void cb5(std::ostream & os, int v) { os << "Value: " << v << "\n"; } + void cb5(std::ostream & os, std::string v) { os << "Value: " << v << "\n"; } } BOOST_AUTO_UNIT_TEST(parsedCommand) @@ -117,12 +118,63 @@ BOOST_AUTO_UNIT_TEST(parsedCommand) { std::stringstream ss; - dir.add("cb", &cb1); - dir.add("cb", &cb5); + 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(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."); dir.add("cb", &cb2); - parser.parse("test/cb 111 222.4; test/cb 222; test/cb", + static_cast(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( boost::ref(executor), boost::ref(ss), _1 )); - BOOST_CHECK_EQUAL( ss.str(), "333\n" "Value: 222\n" "1.2\n" ); + BOOST_CHECK_EQUAL( ss.str(), "333\n" "224\n" "Value: foo\n" "1.2\n" ); + } + + { + std::stringstream ss; + senf::console::root()["test"]("cb").help(ss); + BOOST_CHECK_EQUAL( + ss.str(), + "Usage:\n" + " 1- cb arg11:int [checkup:double]\n" + " 2- cb arg21:string\n" + " 3- cb\n" + "\n" + "With:\n" + " arg11 Bar didelfrump di desgorb. Nu widsoflar brimeldrgf.\n" + " checkup Florgel, dargel and durgel\n" + " default: 2.1\n" + "\n" + "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.\n" + "\n" + "Variant 1:\n" + "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n" + "pupa Sive res indifferenter. Captivo pa.\n" + "\n" + "Variant 2:\n" + "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.\n" ); } } @@ -140,8 +192,8 @@ namespace { std::string name(std::string const & suffix) { return name_ + suffix; } - }; + } BOOST_AUTO_UNIT_TEST(memberParsedCommand) diff --git a/Utils/intrusive_refcount.cti b/Utils/intrusive_refcount.cti index 3e729e0..976e1ae 100644 --- a/Utils/intrusive_refcount.cti +++ b/Utils/intrusive_refcount.cti @@ -43,15 +43,15 @@ prefix_ void senf::intrusive_refcount_base::intrusive_ptr_release() } template -prefix_ void senf::intrusive_ptr_add_ref(intrusive_refcount_t* p) +prefix_ void senf::intrusive_ptr_add_ref(intrusive_refcount_t const * p) { - p->intrusive_ptr_add_ref(); + const_cast*>(p)->intrusive_ptr_add_ref(); } template -prefix_ void senf::intrusive_ptr_release(intrusive_refcount_t* p) +prefix_ void senf::intrusive_ptr_release(intrusive_refcount_t const * p) { - p->intrusive_ptr_release(); + const_cast*>(p)->intrusive_ptr_release(); } template diff --git a/Utils/intrusive_refcount.hh b/Utils/intrusive_refcount.hh index 7fb8f18..b3bfd56 100644 --- a/Utils/intrusive_refcount.hh +++ b/Utils/intrusive_refcount.hh @@ -65,9 +65,9 @@ namespace senf { template void intrusive_ptr_release(); template - friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t * p); + friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t const * p); template - friend void senf::intrusive_ptr_release(intrusive_refcount_t * p); + friend void senf::intrusive_ptr_release(intrusive_refcount_t const * p); }; /** \brief Customizable reference count mixin for intrusive_ptr @@ -158,9 +158,9 @@ namespace senf { }; template - void intrusive_ptr_add_ref(intrusive_refcount_t * p); + void intrusive_ptr_add_ref(intrusive_refcount_t const * p); template - void intrusive_ptr_release(intrusive_refcount_t * p); + void intrusive_ptr_release(intrusive_refcount_t const * p); }