Utils: Fix intrusive_refcount for const objects
g0dil [Wed, 9 Apr 2008 08:56:05 +0000 (08:56 +0000)]
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

15 files changed:
Console/OverloadedCommand.cc
Console/OverloadedCommand.cci
Console/OverloadedCommand.cti
Console/OverloadedCommand.hh
Console/OverloadedCommand.test.cc
Console/ParseParameter.cti
Console/ParseParameter.hh
Console/ParsedCommand.cc
Console/ParsedCommand.cci
Console/ParsedCommand.cti
Console/ParsedCommand.hh
Console/ParsedCommand.mpp
Console/ParsedCommand.test.cc
Utils/intrusive_refcount.cti
Utils/intrusive_refcount.hh

index 5edbd20..47a08dc 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // 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<ArgumentDoc> 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,
index 6fc076d..4892e53 100644 (file)
@@ -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()
 {}
 
index d4d6df8..b5e7a75 100644 (file)
@@ -38,6 +38,7 @@ prefix_ Command &
 senf::console::OverloadedCommandNode::add(boost::intrusive_ptr<Command> overload)
 {
     overloads_.push_back(overload);
+    overload->node_ = this;
     return *overload;
 }
 
index a967120..48b1097 100644 (file)
@@ -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<CommandOverload> ptr;
+        typedef boost::intrusive_ptr<CommandOverload const> 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_;
index 7459086..ad68f57 100644 (file)
@@ -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();
index a36a08c..a88d7f3 100644 (file)
@@ -54,6 +54,13 @@ prefix_ senf::console::detail::ParameterInfo<ParameterType>::ParameterInfo()
       defaultValue ()
 {}
 
+template <class ParameterType>
+prefix_ std::string senf::console::detail::ParameterInfo<ParameterType>::defaultValueStr()
+    const
+{
+    return hasDefault ? ParameterTraits<ParameterType>::dump(defaultValue) : "";
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::detail::ReturnValueTraits<Type>
 
@@ -92,7 +99,15 @@ parse(ParseCommandInfo::TokensRange const & tokens, Type & out)
 template <class Type>
 prefix_ std::string senf::console::detail::ParameterTraits<Type>::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 <class Type>
+prefix_ std::string senf::console::detail::ParameterTraits<Type>::dump(Type const & value)
+{
+    return boost::lexical_cast<std::string>(value);
 }
 
 ///////////////////////////////cti.e///////////////////////////////////////
index 31ac63e..73a8fc6 100644 (file)
@@ -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 <class ParameterType>
@@ -62,6 +65,8 @@ namespace detail {
         ParameterInfo();
 
         ParameterType defaultValue;
+
+        virtual std::string defaultValueStr() const;
     };
     
     template <class Type>
@@ -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);
     };
     
 }}}
index 3a62096..3f27917 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // 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_
index 4d4fc29..94bbf32 100644 (file)
@@ -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_
 
index 9cdb279..60b7fde 100644 (file)
@@ -27,6 +27,7 @@
 
 // Custom includes
 #include "../Utils/membind.hh"
+#include <boost/format.hpp>
 
 #define prefix_ inline
 ///////////////////////////////cti.p///////////////////////////////////////
@@ -39,7 +40,7 @@ prefix_ senf::console::detail::ParameterInfo<Type> &
 senf::console::ParsedCommandOverloadBase::arg(unsigned n)
     const
 {
-    return static_cast<detail::ParameterInfo<Type> &>(arg(n));
+    return dynamic_cast<detail::ParameterInfo<Type> &>(arg(n));
 }
 
 template <class Type>
index b2fca48..70f4203 100644 (file)
@@ -51,20 +51,25 @@ namespace console {
     public:
         typedef boost::intrusive_ptr<ParsedCommandOverloadBase> ptr;
 
-    protected:
-        ParsedCommandOverloadBase();
-
         detail::ParameterInfoBase & arg(unsigned n) const;
         template <class Type> detail::ParameterInfo<Type> & arg(unsigned n) const;
 
+        void doc(std::string const & d);
+
+    protected:
+        ParsedCommandOverloadBase();
+
         template <class Type>
         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<detail::ParameterInfoBase::ptr> Parameters;
         Parameters parameters_;
+        std::string doc_;
     };
 
     template <class FunctionTraits, unsigned arity=FunctionTraits::arity>
index 57948c1..2aadffc 100644 (file)
@@ -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.
index 98a5584..5b90f2c 100644 (file)
@@ -27,6 +27,7 @@
 //#include "ParsedCommand.test.ih"
 
 // Custom includes
+#include <iostream>
 #include <sstream>
 #include "ParsedCommand.hh"
 #include "Executor.hh"
 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<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.");
         dir.add("cb", &cb2);
-        parser.parse("test/cb 111 222.4; test/cb 222; test/cb",
+        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" "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)
index 3e729e0..976e1ae 100644 (file)
@@ -43,15 +43,15 @@ prefix_ void senf::intrusive_refcount_base::intrusive_ptr_release()
 }
 
 template <class Self>
-prefix_ void senf::intrusive_ptr_add_ref(intrusive_refcount_t<Self>* p)
+prefix_ void senf::intrusive_ptr_add_ref(intrusive_refcount_t<Self> const * p)
 {
-    p->intrusive_ptr_add_ref<Self>();
+    const_cast<intrusive_refcount_t<Self>*>(p)->intrusive_ptr_add_ref<Self>();
 }
 
 template <class Self>
-prefix_ void senf::intrusive_ptr_release(intrusive_refcount_t<Self>* p)
+prefix_ void senf::intrusive_ptr_release(intrusive_refcount_t<Self> const * p)
 {
-    p->intrusive_ptr_release<Self>();
+    const_cast<intrusive_refcount_t<Self>*>(p)->intrusive_ptr_release<Self>();
 }
 
 template <class Self>
index 7fb8f18..b3bfd56 100644 (file)
@@ -65,9 +65,9 @@ namespace senf {
         template <class S> void intrusive_ptr_release();
         
         template <class S>
-        friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t<S> * p);
+        friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t<S> const * p);
         template <class S>
-        friend void senf::intrusive_ptr_release(intrusive_refcount_t<S> * p);
+        friend void senf::intrusive_ptr_release(intrusive_refcount_t<S> const * p);
     };
 
     /** \brief Customizable reference count mixin for intrusive_ptr
@@ -158,9 +158,9 @@ namespace senf {
     };
 
     template <class Self>
-    void intrusive_ptr_add_ref(intrusive_refcount_t<Self> * p);
+    void intrusive_ptr_add_ref(intrusive_refcount_t<Self> const * p);
     template <class Self>
-    void intrusive_ptr_release(intrusive_refcount_t<Self> * p);
+    void intrusive_ptr_release(intrusive_refcount_t<Self> const * p);
 
 }