mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
document the primitive equivalence classes
This commit is contained in:
parent
93ae00ce08
commit
d1009c1429
3 changed files with 101 additions and 1 deletions
|
@ -1,19 +1,59 @@
|
||||||
|
// -*- mode: c++ -*-
|
||||||
#ifndef RR_BOOL
|
#ifndef RR_BOOL
|
||||||
#define RR_BOOL
|
#define RR_BOOL
|
||||||
|
|
||||||
namespace rr {
|
namespace rr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seemlessly convert between Ruby booleans and C/C++.
|
||||||
|
*
|
||||||
|
* The `Bool` equivalence lets you plop in a Ruby boolean anywhere
|
||||||
|
* you might need a C++ boolean, and, by the same token, drop in a
|
||||||
|
* C/C++ boolean anywhere you might need a Ruby boolean. E.g.
|
||||||
|
*
|
||||||
|
* // Ruby -> C/C++
|
||||||
|
* if (Bool(Qtrue)) {
|
||||||
|
* //always executed
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // C/C++ -> Ruby
|
||||||
|
* if (RTEST(Bool(true))) {
|
||||||
|
* //always executed
|
||||||
|
* }
|
||||||
|
*/
|
||||||
class Bool : public Equiv {
|
class Bool : public Equiv {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a Bool from a Ruby VALUE
|
||||||
|
*/
|
||||||
Bool(VALUE val) : Equiv(val) {}
|
Bool(VALUE val) : Equiv(val) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructo a Bool from a C/C++ boo. It is immediately
|
||||||
|
* converted into the corresponding;
|
||||||
|
*/
|
||||||
Bool(bool b) : Equiv(b ? Qtrue : Qfalse) {}
|
Bool(bool b) : Equiv(b ? Qtrue : Qfalse) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Bool from JavaScript.
|
||||||
|
*/
|
||||||
Bool(v8::Handle<v8::Boolean> b) : Equiv(b->Value() ? Qtrue : Qfalse) {}
|
Bool(v8::Handle<v8::Boolean> b) : Equiv(b->Value() ? Qtrue : Qfalse) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coerce this into a native C/C++ bool. Since it is stored as a
|
||||||
|
* Ruby VALUE, this is just a simple RTEST.
|
||||||
|
*
|
||||||
|
* bool b = Bool(true); // true
|
||||||
|
* b = Bool(false); // false
|
||||||
|
* b = Bool(Qtrue); // true
|
||||||
|
* b = Bool(Qfalse); // false
|
||||||
|
* b = Bool(Qnil); // false
|
||||||
|
* b = Bool(rb_cObject); // true
|
||||||
|
*/
|
||||||
inline operator bool() {
|
inline operator bool() {
|
||||||
return RTEST(value);
|
return RTEST(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,43 @@
|
||||||
|
// -*- mode: c++ -*-
|
||||||
#ifndef RR_EQUIV
|
#ifndef RR_EQUIV
|
||||||
#define RR_EQUIV
|
#define RR_EQUIV
|
||||||
|
|
||||||
namespace rr {
|
namespace rr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`
|
||||||
|
*/
|
||||||
class Equiv {
|
class Equiv {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs an `Equiv` from a Ruby VALUE. It's up to the
|
||||||
|
* subclass to determine what it can be converted to.
|
||||||
|
*/
|
||||||
Equiv(VALUE val) : value(val) {}
|
Equiv(VALUE val) : value(val) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
*/
|
||||||
inline operator VALUE() { return value; }
|
inline operator VALUE() { return value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,13 +1,41 @@
|
||||||
|
// -*- mode: c++ -*-
|
||||||
#ifndef RR_UINT32
|
#ifndef RR_UINT32
|
||||||
#define RR_UINT32
|
#define RR_UINT32
|
||||||
|
|
||||||
namespace rr {
|
namespace rr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts between Ruby `Number` and the C/C++ `uint32_t`.
|
||||||
|
*
|
||||||
|
* This allows you to easily pass in `uint32_t` values whenever a
|
||||||
|
* Ruby VALUE is expected (such as a method call) E.g.
|
||||||
|
*
|
||||||
|
* uint_32_t myInt = 5;
|
||||||
|
* rb_funcall(UInt32(myInt), rb_intern("to_s")); //=> <String "5">
|
||||||
|
*
|
||||||
|
* It also converts a Ruby `VALUE` into its corresponding
|
||||||
|
* `uint32_t`:
|
||||||
|
*
|
||||||
|
* uint_32_t myInt = UInt32(rb_eval_string("5")); //=> 5
|
||||||
|
*
|
||||||
|
* Like all `Equiv`s, it stores itself internally as a Ruby `VALUE`
|
||||||
|
*/
|
||||||
class UInt32 : public Equiv {
|
class UInt32 : public Equiv {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a UInt32 from a Ruby `VALUE`
|
||||||
|
*/
|
||||||
UInt32(VALUE val) : Equiv(val) {}
|
UInt32(VALUE val) : Equiv(val) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a UInt32 from a `uint32_t` by converting it into its
|
||||||
|
* corresponding `VALUE`.
|
||||||
|
*/
|
||||||
UInt32(uint32_t ui) : Equiv(UINT2NUM(ui)) {}
|
UInt32(uint32_t ui) : Equiv(UINT2NUM(ui)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coerce the Ruby `VALUE` into a `uint32_t`.
|
||||||
|
*/
|
||||||
inline operator uint32_t() {
|
inline operator uint32_t() {
|
||||||
return RTEST(value) ? NUM2UINT(value) : 0;
|
return RTEST(value) ? NUM2UINT(value) : 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue