Thanks again Bob, for posterity here is what I can up with:

 

%typemap(in) const path& {

      $1=NULL;

 

      // check if input is a path already

      void *vptr = 0;

     int res = SWIG_ConvertPtr($input, &vptr, SWIGTYPE_p_openstudio__path, 0);

      if (SWIG_IsOK(res)) {

        if (vptr) {

          // make a new copy, freearg typemap will call delete on this below

          openstudio::path * p = reinterpret_cast< openstudio::path * >(vptr);

          $1 = (openstudio::path *)new openstudio::path(*(openstudio::path const *)p);       

        }else{

          SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "openstudio::path const &", "$symname", 1, $input));

        }

      } else if (TYPE($input) == T_STRING) {

        // otherwise, if a string

        Check_Type($input, T_STRING);

        std::string s(STR2CSTR($input));

        $1 = new openstudio::path(openstudio::toPath(s));

      } else {

        SWIG_exception_fail(SWIG_ArgError(res), Ruby_Format_TypeError( "", "openstudio::path const &", "$symname", 1, $input));

      }

    }

 

    %typemap(freearg) const path& {

      if ($1){

        delete $1;

      }

    }

 

It seems to work for now,
Dan

 

From: Bob Hood [mailto:bhood2@comcast.net]
Sent: Saturday, December 14, 2013 10:59 AM
To: Macumber, Daniel; swig-user@lists.sourceforge.net
Subject: Re: [Swig-user] Implicit conversion in Ruby?

 

On 12/14/2013 9:06 AM, Macumber, Daniel wrote:

Thanks for looking into this Bob!  I think you are right that I want to do an explicit conversion, but I am not understanding how to do that with typemaps.  The problem I am having is that in ruby the input type is String.  SWIG has a map somewhere that converts String to std::string, I want to add one that converts String to path.  I’ve tried looking in the files related to strings in \SWIG\Lib\ruby\ but I am not seeing anything that makes sense to me.

 

  1) Error:

test_funcOnlyTakesAPath(Path_Test):

TypeError: Expected argument 0 of type openstudio::path const &, but got String

"./here"

        in SWIG method 'funcOnlyTakesAPath'

    Path_Test.rb:48:in `funcOnlyTakesAPath'

    Path_Test.rb:48:in `test_funcOnlyTakesAPath'


I can't couch this in terms of Ruby, because I've never wrapped that language.  I have done Python extensively, so here is a SWIG typemap that performs the conversion you're after.

I've defined a simple class:

    class path
    {
    public:
        path(const std::string& str) {}
    };

and a function prototype:

    void funcOnlyTakesAPath(const path& p);

in the same header for SWIG to process.

In my SWIG interface file, I have the following typemap that converts a Python None or string into a path class instance:

    %typemap(in) const path& {
        $1 = NULL;
        if($input == Py_None)
            $1 = new path("");
        else if(PyString_Check($input))
            $1 = new path(PyString_AsString($input));
        else
            SWIG_fail;
    }

    %typemap(freearg) const path& {
        if($1) delete $1;
    }

In Python, invoking this as:

    funcOnlyTakesAPath('./here')

functions as you want, with an instance of the path class being constructed and passed to the internal C++ funcOnlyTakesAPath() function as a 'const path&' type.  You just need to replace the Python API idioms for Ruby in this code to detect and convert the types.