gecoder 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +20 -0
- data/Rakefile +6 -0
- data/ext/extconf.rb +29 -0
- data/ext/missing.cpp +295 -0
- data/ext/missing.h +116 -0
- data/ext/vararray.cpp +312 -0
- data/ext/vararray.h +146 -0
- data/lib/gecoder.rb +4 -0
- data/lib/gecoder/bindings.rb +7 -0
- data/lib/gecoder/bindings/bindings.rb +2055 -0
- data/lib/gecoder/interface.rb +6 -0
- data/lib/gecoder/interface/binding_changes.rb +111 -0
- data/lib/gecoder/interface/branch.rb +102 -0
- data/lib/gecoder/interface/constraints.rb +10 -0
- data/lib/gecoder/interface/constraints/distinct.rb +15 -0
- data/lib/gecoder/interface/constraints/linear.rb +158 -0
- data/lib/gecoder/interface/constraints/relation.rb +76 -0
- data/lib/gecoder/interface/enum_wrapper.rb +64 -0
- data/lib/gecoder/interface/model.rb +130 -0
- data/lib/gecoder/interface/search.rb +23 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -0
- data/vendor/rust/include/rust_conversions.hh +103 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +334 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +98 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +12 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +5 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +35 -0
- data/vendor/rust/test/cppclass.cc +40 -0
- data/vendor/rust/test/cppclass.hh +63 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +77 -0
- metadata +144 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
module Gecode
|
2
|
+
class Model
|
3
|
+
private
|
4
|
+
|
5
|
+
# Wraps a custom enumerable so that constraints can be specified using it.
|
6
|
+
# The argument is altered and returned.
|
7
|
+
def wrap_enum(enum)
|
8
|
+
unless enum.kind_of? Enumerable
|
9
|
+
raise TypeError, 'Only enumerables can be wrapped.'
|
10
|
+
end
|
11
|
+
|
12
|
+
class <<enum
|
13
|
+
include Gecode::IntEnumConstraintMethods
|
14
|
+
end
|
15
|
+
enum.model = self
|
16
|
+
return enum
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# A module containing the methods needed by enumerations containing int
|
21
|
+
# variables. Requires that it's included in an enumerable.
|
22
|
+
module IntEnumConstraintMethods
|
23
|
+
# Specifies that a constraint must hold for the integer variable enum.
|
24
|
+
def must
|
25
|
+
IntVarEnumConstraintExpression.new(active_space, to_int_var_array)
|
26
|
+
end
|
27
|
+
alias_method :must_be, :must
|
28
|
+
|
29
|
+
# Specifies that the negation of a constraint must hold for the integer
|
30
|
+
# variable.
|
31
|
+
def must_not
|
32
|
+
IntVarEnumConstraintExpression.new(active_space, to_int_var_array,
|
33
|
+
true)
|
34
|
+
end
|
35
|
+
alias_method :must_not_be, :must_not
|
36
|
+
|
37
|
+
# Returns an int variable array with all the bound variables.
|
38
|
+
def to_int_var_array
|
39
|
+
elements = to_a
|
40
|
+
arr = Gecode::Raw::IntVarArray.new(active_space, elements.size)
|
41
|
+
elements.each_with_index{ |var, index| arr[index] = var.bind }
|
42
|
+
return arr
|
43
|
+
end
|
44
|
+
|
45
|
+
attr_accessor :model
|
46
|
+
# Gets the current space of the model the array is connected to.
|
47
|
+
def active_space
|
48
|
+
@model.active_space
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Describes a constraint expression that starts with an enumeration of int
|
53
|
+
# variables followed by must or must_not.
|
54
|
+
class IntVarEnumConstraintExpression
|
55
|
+
# Constructs a new expression with the specified space and int var array
|
56
|
+
# with the (bound) variables as source. The expression can optionally be
|
57
|
+
# negated.
|
58
|
+
def initialize(space, var_array, negate = false)
|
59
|
+
@space = space
|
60
|
+
@var_array = var_array
|
61
|
+
@negate = negate
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Gecode
|
2
|
+
# Model is the base class that all models must inherit from. The superclass
|
3
|
+
# constructor must be called.
|
4
|
+
class Model
|
5
|
+
# Design notes: Only one model per problem is used. A model has multiple
|
6
|
+
# spaces. A model has a base space in which it sets up during the
|
7
|
+
# initialization. The model binds the int variables to the current space
|
8
|
+
# upon use.
|
9
|
+
|
10
|
+
# The base from which searches are made.
|
11
|
+
attr :base_space
|
12
|
+
# The currently active space (the one which variables refer to).
|
13
|
+
attr :active_space
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@active_space = @base_space = Gecode::Raw::Space.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# Creates a new integer variable with the specified domain. The domain can
|
20
|
+
# either be a range or a number of elements.
|
21
|
+
def int_var(*domain_args)
|
22
|
+
range = domain_range(*domain_args)
|
23
|
+
index = active_space.new_int_vars(range.begin, range.end).first
|
24
|
+
construct_int_var(index, *domain_args)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates an array containing the specified number of integer variables
|
28
|
+
# with the specified domain. The domain can either be a range or a number
|
29
|
+
# of elements.
|
30
|
+
def int_var_array(count, *domain_args)
|
31
|
+
# TODO: Maybe the custom domain should be specified as an array instead?
|
32
|
+
|
33
|
+
range = domain_range(*domain_args)
|
34
|
+
variables = []
|
35
|
+
active_space.new_int_vars(range.begin, range.end, count).each do |index|
|
36
|
+
variables << construct_int_var(index, *domain_args)
|
37
|
+
end
|
38
|
+
return wrap_enum(variables)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Returns the range of the specified domain arguments, which can either be
|
44
|
+
# given as a range or a number of elements. Raises ArgumentError if no
|
45
|
+
# arguments have been specified.
|
46
|
+
def domain_range(*domain_args)
|
47
|
+
min = max = nil
|
48
|
+
if domain_args.empty?
|
49
|
+
raise ArgumentError, 'A domain has to be specified.'
|
50
|
+
elsif domain_args.size > 1
|
51
|
+
min = domain_args.min
|
52
|
+
max = domain_args.max
|
53
|
+
else
|
54
|
+
element = domain_args.first
|
55
|
+
if element.respond_to? :begin and element.respond_to? :end
|
56
|
+
min = element.begin
|
57
|
+
max = element.end
|
58
|
+
else
|
59
|
+
min = max = element
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return min..max
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates an integer variable from the specified index and domain. The
|
66
|
+
# domain can either be given as a range or as a number of elements.
|
67
|
+
def construct_int_var(index, *domain_args)
|
68
|
+
var = FreeIntVar.new(self, index)
|
69
|
+
|
70
|
+
if domain_args.size > 1
|
71
|
+
# Place an additional domain constraint on the variable with the
|
72
|
+
# arguments as domain.
|
73
|
+
# TODO: use the model's way of defining domain constraints when
|
74
|
+
# available.
|
75
|
+
domain_set = Gecode::Raw::IntSet.new(domain_args, domain_args.size)
|
76
|
+
Gecode::Raw::dom(active_space, var.bind, domain_set,
|
77
|
+
Gecode::Raw::ICL_DEF)
|
78
|
+
end
|
79
|
+
return var
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# An IntVar that is bound to a model, but not to a particular space.
|
84
|
+
class FreeIntVar
|
85
|
+
attr_accessor :model
|
86
|
+
|
87
|
+
# Creates an int variable with the specified index.
|
88
|
+
def initialize(model, index)
|
89
|
+
@model = model
|
90
|
+
@index = index
|
91
|
+
@bound_space = @bound_var = nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# Delegate methods we can't handle to the bound int variable if possible.
|
95
|
+
def method_missing(name, *args)
|
96
|
+
if Gecode::Raw::IntVar.instance_methods.include? name.to_s
|
97
|
+
bind.send(name, *args)
|
98
|
+
else
|
99
|
+
super
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Binds the int variable to the currently active space of the model,
|
104
|
+
# returning the bound int variable.
|
105
|
+
def bind
|
106
|
+
space = active_space
|
107
|
+
unless @bound_space == space
|
108
|
+
# We have not bound the variable to this space, so we do it now.
|
109
|
+
@bound = space.int_var(@index)
|
110
|
+
@bound_space = space
|
111
|
+
end
|
112
|
+
return @bound
|
113
|
+
end
|
114
|
+
|
115
|
+
def inspect
|
116
|
+
if assigned?
|
117
|
+
"#<FreeIntVar range: val.to_s>"
|
118
|
+
else
|
119
|
+
"#<FreeIntVar range: #{min}..#{max}>"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# Returns the space that the int variable should bind to when needed.
|
126
|
+
def active_space
|
127
|
+
@model.active_space
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gecode
|
2
|
+
class Model
|
3
|
+
private
|
4
|
+
|
5
|
+
# Used during the search.
|
6
|
+
COPY_DIST = 16
|
7
|
+
ADAPTATION_DIST = 4
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
# Finds the first solution to the modelled problem and updates the variables
|
12
|
+
# to that solution. Returns the model if a solution was found, nil
|
13
|
+
# otherwise.
|
14
|
+
def solve!
|
15
|
+
stop = Gecode::Raw::Search::Stop.new
|
16
|
+
dfs = Gecode::Raw::DFS.new(@base_space, COPY_DIST, ADAPTATION_DIST, stop)
|
17
|
+
space = dfs.next
|
18
|
+
return nil if space.nil?
|
19
|
+
@active_space = space
|
20
|
+
return self
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/vendor/rust/README
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
When I wanted to write a GUI tagger for KDE using Korundum (KDE Ruby
|
2
|
+
bindings), I discovered to my sadness that most of the tagging
|
3
|
+
extensions for Ruby were simple bindings for the C interface of the
|
4
|
+
most common TagLib library (that is written in C++ instead); writing
|
5
|
+
bindings for the C++ interface was quite a complex task, and boring as
|
6
|
+
it was to copy and paste the same code over and over.
|
7
|
+
|
8
|
+
For this reason I started first writing a simple extensions generator
|
9
|
+
that used a YAML description of the namespaces and the classes to
|
10
|
+
write bindings for. This method worked fine for what I was working on
|
11
|
+
(RubyTag++), and also allowed me to write quite quickly some Ruby
|
12
|
+
bindings for Hunspell too.
|
13
|
+
|
14
|
+
Unfortunately this generator was not adaptable enough to write
|
15
|
+
bindings for C libraries that used some object oriented interfaces,
|
16
|
+
and was a mess to extend to provide bindings more suitable to some
|
17
|
+
different cases than the ones I've already used the script for.
|
18
|
+
|
19
|
+
For this reason I've started working on Rust: a more flexible
|
20
|
+
extensions builder, that allowed to bind even C libraries by faking
|
21
|
+
some classes on Ruby (although I haven't implemented this yet).
|
22
|
+
|
23
|
+
Hopefully in the future Rust can be used to easily produce Ruby
|
24
|
+
bindings for a number of libraries that currently aren't available at
|
25
|
+
all.
|
26
|
+
|
27
|
+
To contact me, send me patches or comments, just write to
|
28
|
+
<flameeyes@gmail.com> .
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
require 'rust/cppifaceparser'
|
3
|
+
|
4
|
+
|
5
|
+
if __FILE__ == $0
|
6
|
+
def usage
|
7
|
+
puts "Use: #{File.basename($0)} [header] [module name] [output file]"
|
8
|
+
end
|
9
|
+
|
10
|
+
parser = Rust::Cpp::IfaceParser.new
|
11
|
+
|
12
|
+
if ARGV.size != 3 or not File.exists?(ARGV[0].to_s)
|
13
|
+
usage
|
14
|
+
exit 0
|
15
|
+
end
|
16
|
+
|
17
|
+
header = ARGV[0]
|
18
|
+
namespace = ARGV[1]
|
19
|
+
outputfile = ARGV[2]
|
20
|
+
outputfile += ".rb" if not outputfile =~ /\.rb$/
|
21
|
+
|
22
|
+
classes = parser.parseFile(header)
|
23
|
+
|
24
|
+
rust = %@
|
25
|
+
require 'rust'
|
26
|
+
|
27
|
+
Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "#{namespace}" do |b|
|
28
|
+
b.include_header '#{header}', Rust::Bindings::HeaderGlobal
|
29
|
+
b.add_namespace "#{namespace}", "" do |ns|
|
30
|
+
@
|
31
|
+
classes.each { |klass|
|
32
|
+
rust += %@ ns.add_cxx_class "#{klass[:name]}" do |klass|\n@
|
33
|
+
klass[:constructors].each { |constructor|
|
34
|
+
rust += " klass.add_constructor "
|
35
|
+
if not constructor[:params].empty? and not constructor[:params].detect { |p| p[:type] =~ /void/ }
|
36
|
+
rust += "do |method|\n"
|
37
|
+
constructor[:params].each { |param|
|
38
|
+
rust += %@ method.add_parameter "#{param[:type]}", "#{param[:name]}"\n@
|
39
|
+
}
|
40
|
+
rust += " end"
|
41
|
+
end
|
42
|
+
rust += "\n"
|
43
|
+
}
|
44
|
+
|
45
|
+
klass[:methods].each { |method|
|
46
|
+
comment_method = false
|
47
|
+
if method[:params].detect { |p| p[:type] =~ /\s*\*\s*\*/ }
|
48
|
+
$stderr << "Ignoring method: #{method[:name]}\n"
|
49
|
+
comment_method = true
|
50
|
+
end
|
51
|
+
|
52
|
+
rust += "# " if comment_method
|
53
|
+
rust += %@ klass.add_method "#{method[:name]}", "#{method[:type]}"@
|
54
|
+
if not method[:params].empty? and not method[:params].detect { |p| p[:type] =~ /void/ }
|
55
|
+
rust += " do |method|\n" if not method[:params].empty?
|
56
|
+
|
57
|
+
|
58
|
+
method[:params].each { |param|
|
59
|
+
rust += "# " if comment_method
|
60
|
+
rust += %@ method.add_parameter "#{param[:type]}", "#{param[:name]}"\n@
|
61
|
+
}
|
62
|
+
rust += "# " if comment_method
|
63
|
+
rust += " end"
|
64
|
+
end
|
65
|
+
|
66
|
+
rust += "\n"
|
67
|
+
}
|
68
|
+
rust += " end\n"
|
69
|
+
}
|
70
|
+
|
71
|
+
rust += %@
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@
|
75
|
+
|
76
|
+
File.open( outputfile, "w" ) { |f|
|
77
|
+
f << rust << "\n"
|
78
|
+
}
|
79
|
+
|
80
|
+
# Create configure.rb
|
81
|
+
File.open( File.dirname(outputfile)+"/configure.rb", "w" ) { |f|
|
82
|
+
f << %@
|
83
|
+
require 'mkmf'
|
84
|
+
find_header("rust_conversions.hh", "./include" )
|
85
|
+
eval File.open("#{File.basename(outputfile)}").readlines.to_s
|
86
|
+
create_makefile("#{namespace}")
|
87
|
+
@
|
88
|
+
}
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
/* Copyright (c) 2007 David Cuadrado <krawek@gmail.com>
|
2
|
+
*
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
* a copy of this software and associated documentation files (the
|
5
|
+
* "Software"), to deal in the Software without restriction, including
|
6
|
+
* without limitation the rights to use, copy, modify, merge,
|
7
|
+
* publish, distribute, sublicense, and/or sell copies of the Software,
|
8
|
+
* and to permit persons to whom the Software is furnished to do so,
|
9
|
+
* subject to the following conditions:
|
10
|
+
*
|
11
|
+
* The above copyright notice and this permission notice shall be
|
12
|
+
* included in all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
18
|
+
* BE LIABLE
|
19
|
+
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
20
|
+
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
*/
|
23
|
+
|
24
|
+
#ifndef __RUST_CHECKS__
|
25
|
+
#define __RUST_CHECKS__
|
26
|
+
|
27
|
+
#include <ruby.h>
|
28
|
+
|
29
|
+
static inline void rust_CheckType(VALUE *a)
|
30
|
+
{
|
31
|
+
Check_Type(a[0], NUM2INT(a[1]));
|
32
|
+
}
|
33
|
+
|
34
|
+
static inline bool isType(VALUE val, int type)
|
35
|
+
{
|
36
|
+
int result;
|
37
|
+
if( type == 0x0 ) return false;
|
38
|
+
|
39
|
+
VALUE args[2];
|
40
|
+
args[0] = (VALUE)val;
|
41
|
+
args[1] = INT2FIX(type);
|
42
|
+
|
43
|
+
rb_protect( (VALUE(*)(VALUE))rust_CheckType, (VALUE)args, &result);
|
44
|
+
return result == 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
static inline bool is_object(VALUE val)
|
49
|
+
{
|
50
|
+
return isType(val, T_OBJECT);
|
51
|
+
}
|
52
|
+
|
53
|
+
static inline bool is_class(VALUE val)
|
54
|
+
{
|
55
|
+
return isType(val, T_CLASS);
|
56
|
+
}
|
57
|
+
|
58
|
+
static inline bool is_module(VALUE val)
|
59
|
+
{
|
60
|
+
return isType(val, T_MODULE);
|
61
|
+
}
|
62
|
+
|
63
|
+
static inline bool is_fLoat(VALUE val)
|
64
|
+
{
|
65
|
+
return isType(val, T_FLOAT);
|
66
|
+
}
|
67
|
+
|
68
|
+
static inline bool is_string(VALUE val)
|
69
|
+
{
|
70
|
+
return isType(val, T_STRING);
|
71
|
+
}
|
72
|
+
|
73
|
+
static inline bool is_regexp(VALUE val)
|
74
|
+
{
|
75
|
+
return isType(val, T_REGEXP);
|
76
|
+
}
|
77
|
+
|
78
|
+
static inline bool is_array(VALUE val)
|
79
|
+
{
|
80
|
+
return isType(val, T_ARRAY);
|
81
|
+
}
|
82
|
+
|
83
|
+
static inline bool is_int(VALUE val)
|
84
|
+
{
|
85
|
+
return isType(val, T_FIXNUM);
|
86
|
+
}
|
87
|
+
|
88
|
+
static inline bool is_hash(VALUE val)
|
89
|
+
{
|
90
|
+
return isType(val, T_HASH);
|
91
|
+
}
|
92
|
+
|
93
|
+
static inline bool is_symbol(VALUE val)
|
94
|
+
{
|
95
|
+
return isType(val, T_SYMBOL);
|
96
|
+
}
|
97
|
+
|
98
|
+
static inline bool is_bool(VALUE val)
|
99
|
+
{
|
100
|
+
return val == Qtrue || val == Qfalse;
|
101
|
+
}
|
102
|
+
|
103
|
+
static inline bool is_charPtr(VALUE val)
|
104
|
+
{
|
105
|
+
char *c = 0;
|
106
|
+
c = reinterpret_cast<char *>(DATA_PTR(val));
|
107
|
+
|
108
|
+
return c != 0; // FIXME
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
#endif
|
115
|
+
|