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
|
||||
#define RR_BOOL
|
||||
|
||||
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 {
|
||||
public:
|
||||
/**
|
||||
* Construct a Bool from a Ruby VALUE
|
||||
*/
|
||||
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) {}
|
||||
|
||||
/**
|
||||
* Construct a Bool from JavaScript.
|
||||
*/
|
||||
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() {
|
||||
return RTEST(value);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,43 @@
|
|||
// -*- mode: c++ -*-
|
||||
#ifndef RR_EQUIV
|
||||
#define RR_EQUIV
|
||||
|
||||
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 {
|
||||
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) {}
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1,13 +1,41 @@
|
|||
// -*- mode: c++ -*-
|
||||
#ifndef RR_UINT32
|
||||
#define RR_UINT32
|
||||
|
||||
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 {
|
||||
public:
|
||||
/**
|
||||
* Construct a UInt32 from a Ruby `VALUE`
|
||||
*/
|
||||
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)) {}
|
||||
|
||||
/**
|
||||
* Coerce the Ruby `VALUE` into a `uint32_t`.
|
||||
*/
|
||||
inline operator uint32_t() {
|
||||
return RTEST(value) ? NUM2UINT(value) : 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue