2015-06-29 19:06:12 +03:00
|
|
|
// -*- mode: c++ -*-
|
2015-03-20 20:47:57 +00:00
|
|
|
#ifndef RR_EQUIV
|
|
|
|
#define RR_EQUIV
|
|
|
|
|
|
|
|
namespace rr {
|
|
|
|
|
2015-06-29 19:06:12 +03:00
|
|
|
/**
|
|
|
|
* Defines an equivalence between a primitive Ruby and C/C++ types so
|
|
|
|
* that they can be used inter-changeably. In other words: given a
|
|
|
|
* Ruby `VALUE` it can convert it to a C/C++ type, and given a C/C++
|
|
|
|
* type, it can convert it to a Ruby type. For example, the Boolean
|
|
|
|
* equivalence class defines the relationship between Ruby booleans
|
|
|
|
* and C/++ booleans, and can be used to place a Ruby VALUE anywhere
|
|
|
|
* you might need a C/C++ boolean such as an "if" statement:
|
|
|
|
*
|
|
|
|
* if (rr::Bool(Qnil)) { //
|
|
|
|
* throw "not going to happen!";
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* This is the superclass of all equivalences classes,
|
|
|
|
* and is not meant to be instantiated.
|
|
|
|
*
|
|
|
|
* Internally, `Equiv`s are always stored as a Ruby `VALUE`, and so
|
|
|
|
* part of the job of the subclass is to have an appropriate
|
|
|
|
* constructor that converts the C/C++ type to a `VALUE`
|
|
|
|
*/
|
2015-03-20 20:47:57 +00:00
|
|
|
class Equiv {
|
|
|
|
public:
|
2015-06-29 19:06:12 +03:00
|
|
|
/**
|
|
|
|
* Constructs an `Equiv` from a Ruby VALUE. It's up to the
|
|
|
|
* subclass to determine what it can be converted to.
|
|
|
|
*/
|
2015-03-20 20:47:57 +00:00
|
|
|
Equiv(VALUE val) : value(val) {}
|
2015-06-29 19:06:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts this `Equiv` into a Ruby `VALUE`. This, of course, is
|
|
|
|
* just the value of the internal storage. In the Boolean example:
|
|
|
|
*
|
|
|
|
* VALUE val = Bool(Qnil); //=> Qnil;
|
|
|
|
*/
|
2015-03-20 20:47:57 +00:00
|
|
|
inline operator VALUE() { return value; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
VALUE value;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|