C++ as_an_fparam() in SaferCPlusPlus














































C++ as_an_fparam() in SaferCPlusPlus



C++ as_an_fparam() in SaferCPlusPlus


rsv::TFParam<> is just a transparent template wrapper for function parameter declarations. In most cases, the use of this wrapper is not necessary, but in some cases, it enables functionality only available to variables that are function parameters. Specifically, it allows functions to support arguments that are scope pointers/references to temporary objects. For safety reasons, by default, scope pointer/references to temporaries are actually “functionally disabled” types distinct from regular scope pointer/reference types.

Because it’s safe to do so in the case of function parameters, the rsv::TFParam<> wrapper enables certain scope pointer/reference types (like TXScopeFixedConstPointer<>, and “random access const sections” scope types) to be constructed from their “functionally disabled” counterparts.

In the case of function templates, sometimes you want the parameter types to be auto-deduced, and the use of the mse::rsv::TFParam<> wrapper can interfere with that. In those cases, you can instead convert parameters to their wrapped type after-the-fact using the rsv::as_an_fparam() function. Note that using this function (or the rsv::TFParam<> wrapper) on anything other than function parameters would be unsafe, and wouldn’t be prevented by the type system. Safety enforcement is reliant on a companion tool like scpptool.

rsv::TXScopeFParam<> and rsv::xscope_as_an_fparam() can be used for situations when the types are necessarily scope types.

Code:

#include "msescope.h"
#include "msemsestring.h"
#include "msepoly.h"
   
class H {
public:
    /* This function will be used to demonstrate using rsv::as_an_fparam() to enable
template functions to accept scope pointers to temporary objects. */
    template<class _TPointer1, class _TPointer2>
    static bool second_is_longer(_TPointer1&& string1_xscpptr,
_TPointer2&& string2_xscpptr) {
    auto l_string1_xscpptr = mse::rsv::as_an_fparam
(std::forward<decltype(string1_xscpptr)>(string1_xscpptr));
    auto l_string2_xscpptr = mse::rsv::as_an_fparam
(std::forward<decltype(string2_xscpptr)>(string2_xscpptr));
    return (l_string1_xscpptr->length() > l_string2_xscpptr->length()) ? false : true;
    }
};
   
void main(int argc, char* argv[]) {
    class CD {
    public:
        static bool second_is_longer(mse::rsv::TXScopeFParam<mse::
TXScopeFixedConstPointer<mse::nii_string> > string1_xscpptr
        , mse::rsv::TXScopeFParam<mse::TXScopeFixedConstPointer<mse::nii_string>
> string2_xscpptr) {

    return (string1_xscpptr->length() > string2_xscpptr->length()) ? false : true;
        }

        static bool second_is_longer_any(mse::rsv::TXScopeFParam<mse::
TXScopeAnyConstPointer<mse::nii_string> > string1_xscpptr
        , mse::rsv::TXScopeFParam<mse::TXScopeAnyConstPointer<mse::nii_string> >
string2_xscpptr) {
        return (string1_xscpptr->length() > string2_xscpptr->length()) ? false : true;
        }

        static bool second_is_longer_poly(mse::rsv::TXScopeFParam<mse::
TXScopePolyConstPointer<mse::nii_string> > string1_xscpptr
        , mse::rsv::TXScopeFParam<mse::TXScopePolyConstPointer<mse::nii_string> >
string2_xscpptr) {
        return (string1_xscpptr->length() > string2_xscpptr->length()) ? false : true;
        }
    };

    mse::TXScopeObj<mse::nii_string> xscope_string1 = "abc";
    /* Here we're using the pointer_to() function to obtain a ("caged") pointer to
the temporary scope object. The '&' (ampersand) operator would also work, but
would not correspond to valid native C++, as C++ does not support taking the
address of an r-value. */
    auto res1 = CD::second_is_longer(&xscope_string1, mse::pointer_to
(mse::TXScopeObj<mse::nii_string>(xscope_string1 + "de")));
    auto res2 = H::second_is_longer(&xscope_string1, mse::pointer_to
(mse::TXScopeObj<mse::nii_string>(xscope_string1 + "de")));
    auto res3 = CD::second_is_longer_any(&xscope_string1, mse::pointer_to
(mse::TXScopeObj<mse::nii_string>(xscope_string1 + "de")));
    auto res4 = CD::second_is_longer_poly(&xscope_string1, mse::pointer_to
(mse::TXScopeObj<mse::nii_string>(xscope_string1 + "de")));
}

Comments