autoc 1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +3 -0
  3. data/README.md +149 -0
  4. data/cmake/AutoC.cmake +39 -0
  5. data/lib/autoc/allocators.rb +51 -0
  6. data/lib/autoc/association.rb +126 -0
  7. data/lib/autoc/box.rb +311 -0
  8. data/lib/autoc/cmake.rb +54 -0
  9. data/lib/autoc/collection.rb +83 -110
  10. data/lib/autoc/composite.rb +333 -0
  11. data/lib/autoc/cstring.rb +263 -0
  12. data/lib/autoc/function.rb +247 -0
  13. data/lib/autoc/hash_map.rb +328 -0
  14. data/lib/autoc/hash_set.rb +339 -0
  15. data/lib/autoc/hashers.rb +102 -0
  16. data/lib/autoc/list.rb +444 -0
  17. data/lib/autoc/module.rb +434 -0
  18. data/lib/autoc/openmp.rb +15 -0
  19. data/lib/autoc/primitive.rb +27 -0
  20. data/lib/autoc/ranges.rb +707 -0
  21. data/lib/autoc/record.rb +247 -0
  22. data/lib/autoc/scaffold/docs.rb +117 -0
  23. data/lib/autoc/scaffold/generic_value.rb +86 -0
  24. data/lib/autoc/scaffold/project.rb +75 -0
  25. data/lib/autoc/scaffold/test_cstring.rb +113 -0
  26. data/lib/autoc/scaffold/test_cstring_hash_set.rb +35 -0
  27. data/lib/autoc/scaffold/test_int_box.rb +22 -0
  28. data/lib/autoc/scaffold/test_int_hash_set.rb +448 -0
  29. data/lib/autoc/scaffold/test_int_list.rb +106 -0
  30. data/lib/autoc/scaffold/test_int_vector.rb +83 -0
  31. data/lib/autoc/scaffold/test_v2v_hash_map.rb +83 -0
  32. data/lib/autoc/scaffold/test_value_hash_set.rb +60 -0
  33. data/lib/autoc/scaffold/test_value_vector.rb +146 -0
  34. data/{test/test.rb → lib/autoc/scaffold/tests.rb} +179 -158
  35. data/lib/autoc/scaffold.rb +12 -0
  36. data/lib/autoc/sequential.rb +99 -0
  37. data/lib/autoc/set.rb +331 -0
  38. data/lib/autoc/std.rb +149 -0
  39. data/lib/autoc/type.rb +93 -531
  40. data/lib/autoc/vector.rb +290 -0
  41. data/lib/autoc.rb +4 -35
  42. metadata +55 -85
  43. data/.yardopts +0 -4
  44. data/CHANGES +0 -23
  45. data/README +0 -28
  46. data/doc/AutoC/Code.html +0 -523
  47. data/doc/AutoC/Collection.html +0 -1214
  48. data/doc/AutoC/HashMap.html +0 -1441
  49. data/doc/AutoC/HashSet.html +0 -916
  50. data/doc/AutoC/Iterators/Bidirectional.html +0 -204
  51. data/doc/AutoC/Iterators/Unidirectional.html +0 -200
  52. data/doc/AutoC/Iterators.html +0 -126
  53. data/doc/AutoC/List.html +0 -1039
  54. data/doc/AutoC/Maps.html +0 -290
  55. data/doc/AutoC/Module/File.html +0 -415
  56. data/doc/AutoC/Module/Header.html +0 -437
  57. data/doc/AutoC/Module/Source.html +0 -707
  58. data/doc/AutoC/Module.html +0 -948
  59. data/doc/AutoC/Priority.html +0 -138
  60. data/doc/AutoC/Queue.html +0 -1172
  61. data/doc/AutoC/Reference.html +0 -735
  62. data/doc/AutoC/Sets.html +0 -520
  63. data/doc/AutoC/String.html +0 -1394
  64. data/doc/AutoC/TreeMap.html +0 -1565
  65. data/doc/AutoC/TreeSet.html +0 -1447
  66. data/doc/AutoC/Type.html +0 -2148
  67. data/doc/AutoC/UserDefinedType.html +0 -1047
  68. data/doc/AutoC/Vector.html +0 -987
  69. data/doc/AutoC.html +0 -331
  70. data/doc/_index.html +0 -388
  71. data/doc/class_list.html +0 -51
  72. data/doc/css/common.css +0 -1
  73. data/doc/css/full_list.css +0 -58
  74. data/doc/css/style.css +0 -481
  75. data/doc/file.CHANGES.html +0 -117
  76. data/doc/file.README.html +0 -116
  77. data/doc/file_list.html +0 -61
  78. data/doc/frames.html +0 -17
  79. data/doc/index.html +0 -116
  80. data/doc/js/app.js +0 -243
  81. data/doc/js/full_list.js +0 -216
  82. data/doc/js/jquery.js +0 -4
  83. data/doc/method_list.html +0 -1307
  84. data/doc/top-level-namespace.html +0 -112
  85. data/lib/autoc/code.rb +0 -237
  86. data/lib/autoc/collection/hash_map.rb +0 -385
  87. data/lib/autoc/collection/hash_set.rb +0 -337
  88. data/lib/autoc/collection/iterator.rb +0 -39
  89. data/lib/autoc/collection/list.rb +0 -429
  90. data/lib/autoc/collection/map.rb +0 -41
  91. data/lib/autoc/collection/queue.rb +0 -517
  92. data/lib/autoc/collection/set.rb +0 -134
  93. data/lib/autoc/collection/tree_map.rb +0 -464
  94. data/lib/autoc/collection/tree_set.rb +0 -611
  95. data/lib/autoc/collection/vector.rb +0 -336
  96. data/lib/autoc/string.rb +0 -492
  97. data/test/test_auto.c +0 -7141
  98. data/test/test_auto.h +0 -753
  99. data/test/test_char_string.rb +0 -270
  100. data/test/test_int_list.rb +0 -35
  101. data/test/test_int_tree_set.rb +0 -111
  102. data/test/test_int_vector.rb +0 -34
  103. data/test/test_value_hash_map.rb +0 -162
  104. data/test/test_value_hash_set.rb +0 -173
  105. data/test/test_value_list.rb +0 -193
  106. data/test/test_value_queue.rb +0 -275
  107. data/test/test_value_tree_map.rb +0 -176
  108. data/test/test_value_tree_set.rb +0 -173
  109. data/test/test_value_vector.rb +0 -155
  110. data/test/value.rb +0 -80
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'digest'
5
+ require 'autoc/module'
6
+
7
+
8
+ module AutoC
9
+
10
+
11
+ # CMake package renderer for the AutoC module
12
+ class CMake
13
+
14
+ attr_reader :module
15
+
16
+ def file_name = "#{self.module.name}.cmake"
17
+
18
+ def initialize(m) = @module = m
19
+
20
+ def render
21
+ m = self.module
22
+ sources = self.module.sources.collect { |s| "${CMAKE_CURRENT_SOURCE_DIR}/#{s.file_name}" } .join(' ')
23
+ stream = %{
24
+ set(#{m.name}_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/#{m.header.file_name})
25
+ set(#{m.name}_SOURCES #{sources})
26
+ add_library(#{m.name} OBJECT ${#{m.name}_SOURCES})
27
+ target_include_directories(#{m.name} INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
28
+ }
29
+ unless Digest::MD5.digest(stream) == (Digest::MD5.digest(File.read(file_name)) rescue nil)
30
+ File.write(file_name, stream)
31
+ end
32
+ end
33
+
34
+ def self.render(m) = self.new(m).render
35
+
36
+ end # CMake
37
+
38
+
39
+ end
40
+
41
+
42
+ ### On code generation vs. CMake
43
+
44
+ # https://here-be-braces.com/integrating-a-flexible-code-generator-into-cmake/
45
+ # https://blog.kangz.net/posts/2016/05/26/integrating-a-code-generator-with-cmake/
46
+
47
+
48
+ ### On code packaging
49
+
50
+ # https://www.youtube.com/watch?v=sBP17HQAQjk
51
+ # https://www.youtube.com/watch?v=_5weX5mx8hc
52
+
53
+ # https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html
54
+ # https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html
@@ -1,145 +1,118 @@
1
- require "autoc/code"
2
- require "autoc/type"
1
+ # frozen_string_literal: true
3
2
 
4
3
 
5
- module AutoC
6
-
7
-
8
- =begin
4
+ require 'autoc/std'
5
+ require 'autoc/composite'
9
6
 
10
- == Implemented types
11
7
 
12
- - {AutoC::UserDefinedType} user-defined custom type
13
-
14
- - {AutoC::Reference} counted reference type
8
+ module AutoC
15
9
 
16
- - {AutoC::String} string builder type with value semantics
17
10
 
18
- == Implemented collections
11
+ using STD::Coercions
12
+
19
13
 
20
- - {AutoC::Vector} resizable array
14
+ # @abstract
15
+ # Generator for C types which contain zero or more elements of a particular type
16
+ class Collection < Composite
21
17
 
22
- - {AutoC::List} singly linked list
18
+ attr_reader :element
23
19
 
24
- - {AutoC::Queue} doubly linked list
20
+ attr_reader :range
25
21
 
26
- - {AutoC::HashSet} hash-based unordered set
22
+ def self.new(*args, **kws)
23
+ obj = super
24
+ obj.references << obj.range # Range has to be referenced after the iterable object gets fully configured
25
+ obj
26
+ end
27
27
 
28
- - {AutoC::HashMap} hash-based unordered map
28
+ def initialize(signature, element, **kws)
29
+ super(signature, **kws)
30
+ dependencies << (@element = element.to_type)
31
+ end
29
32
 
30
- - {AutoC::TreeSet} tree-based sorted set
33
+ # For container to be copyable a copyable element type is required
34
+ def copyable? = super && element.copyable?
31
35
 
32
- - {AutoC::TreeMap} tree-based sorted map
36
+ # For container to be comparable a comparable element type is required
37
+ def comparable? = super && element.comparable?
33
38
 
34
- == Ruby side operation
39
+ # For container to be orderable an orderable element type is required
40
+ def orderable? = super && element.orderable?
35
41
 
36
- .Complete example for generation of a list of integers collection:
37
- [source,ruby]
38
- ----
39
- require "autoc"
40
- AutoC::Module.generate!(:Test) do |c|
41
- c << AutoC::List.new(:IntList, :int)
42
- end
43
- ----
44
- In the above example a C module Test represented by the C header +test_auto.h+ and the C source +test_auto.c+ is generated.
45
- The C++ counterpart of the generated collection is +std::forward_list<int>+.
42
+ # A destructible element type mandates creation of the container's destructor
43
+ def destructible? = super || element.destructible?
46
44
 
47
- == C interface
45
+ # For container to be hashable a hashable element type is required
46
+ def hashable? = super && element.hashable?
47
+
48
+ def type_tag = "#{signature}<#{element}>"
48
49
 
49
- === Element types: values, references
50
+ private
50
51
 
51
- Collections may contain both value and reference types, including other collections.
52
+ def configure
53
+ super
54
+ method(:int, :empty, { target: const_rvalue })
55
+ method(:size_t, :size, { target: const_rvalue })
56
+ # Separate certain methods creation from documenting due to mutual dependency
57
+ empty.configure do
58
+ header %{
59
+ @brief Check container for emptiness
52
60
 
53
- === Thread safety
61
+ @param[in] target container to check
62
+ @return non-zero value if container is empty (i.e. contains no elements) and zero value otherwise
54
63
 
55
- WARNING: In its current state the implemented collections are *not* thread-safe.
64
+ @note This function's behavior must be consistent with @ref #{size}.
56
65
 
57
- === Iteration
66
+ @since 2.0
67
+ }
68
+ end
69
+ size.configure do
70
+ header %{
71
+ @brief Return number of contained elements
58
72
 
59
- At the moment a fairly simple iteration functionality is implemented.
60
- The iterators are modeled after the C# language.
61
- All implemented iterators do not require destruction after use.
73
+ @param[in] target container to query
74
+ @return number of contained elements
62
75
 
63
- .Basic iterator usage example:
64
- [source,c]
65
- ----
66
- MyVector c;
67
- MyVectorIt it;
68
- ...
69
- MyVectorItCtor(&it, &c);
70
- while(MyVectorItMove(&it)) {
71
- Element e = MyVectorItGet(&it);
72
- ...
73
- ElementDtor(e);
74
- }
75
- ----
76
+ @note This function's behavior must be consistent with @ref #{empty}.
76
77
 
77
- WARNING: the collection being iterated *must not* be modified in any way otherwise the iterator behavior is undefined.
78
- =end
79
- class Collection < Type
78
+ @since 2.0
79
+ }
80
+ end
81
+ method(:int, :contains, { target: const_rvalue, value: element.const_rvalue }, constraint:-> { element.comparable? }).configure do
82
+ header %{
83
+ @brief Look up for specific element in container
80
84
 
81
- include Redirecting
82
-
83
- attr_reader :element, :it_ref
84
-
85
- def hash; super ^ element.hash end
86
-
87
- def ==(other) super && element == other.element end
88
-
89
- alias :eql? :==
85
+ @param[in] target container to query
86
+ @param[in] value element to look for
87
+ @return non-zero value if container has (at least one) element equal to the specified value and zero value otherwise
90
88
 
91
- def entities; super << element end
92
-
93
- def initialize(type_name, element_type, visibility = :public)
94
- super(type_name, visibility)
95
- @it_ref = "#{it}*"
96
- @element = Type.coerce(element_type)
97
- initialize_redirectors
98
- element_requirement(element)
99
- end
100
-
101
- # Normally all collections are expected to provide all special functions
102
- # If a collection does not provide specific function it should override the respective method
103
-
104
- # Collection always has default constructor
105
- def constructible?; true end
89
+ This function scans through the container's contents to look for an element which is considered equal to the specified value.
90
+ The equality testing is performed with the element type's equality criterion.
106
91
 
107
- # Collection always has constructor
108
- def initializable?; true end
92
+ @since 2.0
93
+ }
94
+ end
95
+ method(element.const_lvalue, :find_first, { target: const_rvalue, value: element.const_rvalue }, constraint:-> { element.comparable? }).configure do
96
+ header %{
97
+ @brief Search for specific element
109
98
 
110
- # Collection always has destructor but the element is required to be destructible on its own
111
- # because collection destruction incurs destruction of all contained elements
112
- def destructible?; true && element.destructible? end
99
+ @param[in] target container to search through
100
+ @param[in] value value to look for
101
+ @return a view of element equivalent to specified value or NULL value
113
102
 
114
- # Collection always has copy constructor but the element is required to be copyable on its own
115
- # because collection copying incurs copying of all contained elements
116
- def copyable?; true && element.copyable? end
103
+ This function scans through `target` and returns a constant reference (in form of the C pointer)
104
+ a contained element equivalent to the specified `target` or NULL value is there is no such element.
117
105
 
118
- # Collection always has equality tester but the element is required to be comparable on its own
119
- # because collection comparison incurs comparison of all contained elements
120
- def comparable?; true && element.comparable? end
106
+ This function usually (but not neccessarily) yields first suitable element.
121
107
 
122
- # So far there are no orderable collections therefore inherit false-returning #orderable?
108
+ This function requires the element type to be *comparable* (i.e. to have a well-defined comparison operation).
123
109
 
124
- # Collection always has hash calculation function but the element is required to be hashable on its own
125
- # because collection comparison incurs hash calculation for all contained elements
126
- def hashable?
127
- # Since using collection as an element of a hash-based container also requires it to be comparable as well
128
- comparable? && element.hashable?
129
- end
110
+ @since 2.0
111
+ }
112
+ end
113
+ end
130
114
 
131
- def write_intf_decls(stream, declare, define)
132
- write_redirectors(stream, declare, define)
133
- end
134
-
135
- private
136
-
137
- def element_requirement(obj)
138
- raise "type #{obj.type} (#{obj}) must be destructible" unless obj.destructible?
139
- raise "type #{obj.type} (#{obj}) must be copyable" unless obj.copyable?
140
- end
141
-
142
- end # Collection
115
+ end # Collection
143
116
 
144
117
 
145
- end # AutoC
118
+ end
@@ -0,0 +1,333 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'autoc/std'
5
+ require 'autoc/type'
6
+ require 'autoc/module'
7
+ require 'autoc/hashers'
8
+ require 'autoc/allocators'
9
+ require 'autoc/function'
10
+
11
+
12
+ module AutoC
13
+
14
+
15
+ using STD::Coercions
16
+
17
+
18
+ # @abstract
19
+ class Composite < Type
20
+
21
+ PRIVATE = '/** @private */'
22
+
23
+ include STD
24
+
25
+ include Entity
26
+
27
+ attr_reader :visibility
28
+
29
+ attr_reader :_master # Internal reference to the containing type if this type is used as implementing type
30
+
31
+ def initialize(signature, visibility: :public, decorator: nil, allocator: nil, hasher: nil, _master: nil)
32
+ super(signature)
33
+ @methods = {}
34
+ @hasher = hasher
35
+ @decorator = decorator
36
+ @allocator = allocator
37
+ @visibility = visibility
38
+ dependencies << DEFINITIONS << ASSERT_H << self.memory << self.hasher
39
+ @_master = _master
40
+ end
41
+
42
+ def self.new(*args, **kws, &block)
43
+ obj = super
44
+ obj.send(:configure)
45
+ obj
46
+ end
47
+
48
+ def to_value = Value.new(self)
49
+
50
+ def rvalue = @rv ||= Value.new(self, reference: true)
51
+
52
+ def lvalue = @lv ||= Value.new(self, reference: true)
53
+
54
+ def const_rvalue = @crv ||= Value.new(self, constant: true, reference: true)
55
+
56
+ def const_lvalue = @clv ||= Value.new(self, constant: true, reference: true)
57
+
58
+ # Prefix used to generate type-qualified identifiers
59
+ # By default it returns the C side type signature but can be overridden
60
+ # to handle the cases where the signature is not itself a valid C identifier (char*, for example)
61
+ def prefix = signature
62
+
63
+ def inspect = "#{signature} <#{self.class}>"
64
+
65
+ # Decorate identifier with type-specific prefix
66
+ def identifier(id, **kws) = (@decorator.nil? ? Composite.decorator : @decorator).(self, id, **kws)
67
+
68
+ def public? = @visibility == :public
69
+
70
+ def respond_to_missing?(meth, include_private = false) = @methods.has_key?(meth) ? true : super
71
+
72
+ def type_tag = signature
73
+
74
+ def defgroup = (public? ? :@public : :@internal).to_s + " @defgroup #{signature} #{type_tag}"
75
+
76
+ def ingroup = (public? ? :@public : :@internal).to_s + " @ingroup #{signature}"
77
+
78
+ def memory = (@allocator.nil? ? Composite.allocator : @allocator)
79
+
80
+ def hasher = (@hasher.nil? ? Composite.hasher : @hasher)
81
+
82
+ def self.decorator=(decorator) @decorator = decorator end
83
+
84
+ def self.decorator = @decorator
85
+
86
+ def self.allocator=(allocator) @allocator = allocator end
87
+
88
+ def self.allocator = @allocator
89
+
90
+ self.allocator = Allocator.instance # Standard C malloc() & free() memory handler
91
+
92
+ def self.hasher=(hasher) @hasher = hasher end
93
+
94
+ def self.hasher = @hasher
95
+
96
+ self.hasher = Hasher.instance # Default cycle-xor hasher
97
+
98
+ # Pluggable CamelCase identifier decorator
99
+ CAMEL_CASE_DECORATOR = -> (type, symbol, abbreviate: false, **kws) {
100
+ id = symbol.to_s.sub(/[!?]$/, '') # Strip trailing !?
101
+ _ = # Check for leading underscore
102
+ if /^(_+)(.*)/ =~ id
103
+ id = Regexp.last_match(2) # Chop leading underscore
104
+ true
105
+ else
106
+ false
107
+ end
108
+ id = id[0] if abbreviate
109
+ # Convert _separated_names to the CamelCase
110
+ id = type.prefix + id.split('_').collect{ |s| s[0].upcase << s[1..-1] }.join
111
+ # Carry over the method name's leading underscore only if the prefix is not in turn underscored
112
+ _ && !type.prefix.start_with?('_') ? Regexp.last_match(1) + id : id
113
+ }
114
+
115
+ # Pluggable _snake_case identifier decorator
116
+ SNAKE_CASE_DECORATOR = -> (type, symbol, abbreviate: false, **kws) {
117
+ id = symbol.to_s.sub(/[!?]$/, '') # Strip trailing !?
118
+ # Check for leading underscore
119
+ _ =
120
+ if /^(_+)(.*)/ =~ id
121
+ id = Regexp.last_match(2)
122
+ true
123
+ else
124
+ false
125
+ end
126
+ id = abbreviate ? "#{type.prefix}#{id[0]}" : "#{type.prefix}_#{id}"
127
+ # Carry over the method name's leading underscore only if the prefix is not in turn underscored
128
+ _ && !type.prefix.start_with?('_') ? Regexp.last_match(1) + id : id
129
+ }
130
+
131
+ self.decorator = CAMEL_CASE_DECORATOR
132
+
133
+ private
134
+
135
+ def method_missing(meth, *args)
136
+ if (method = @methods[meth]).nil?
137
+ # On anything thats not a defined method return a type-decorated identifier
138
+ # This allows to generate arbitrary type-qualified identifiers with #{type.foo}
139
+ raise "unexpected arguments" unless args.empty?
140
+ identifier(meth)
141
+ else
142
+ method
143
+ end
144
+ end
145
+
146
+ # Overridable for custom method in derived classes
147
+ def method_class = Method
148
+
149
+ # Create a new type-bound function (aka method)
150
+ def method(result, name, parameters, inline: false, visibility: nil, constraint: true, instance: name, **kws)
151
+ method = method_class.new(
152
+ self,
153
+ result,
154
+ name,
155
+ parameters, # TODO force parameter types coercion
156
+ inline:,
157
+ visibility: (visibility.nil? ? self.visibility : visibility), # Method's visibility property can be borrowed from the type itself
158
+ constraint: constraint,
159
+ **kws
160
+ )
161
+ raise "##{instance} method redefinition is not allowed" if @methods.has_key?(instance)
162
+ @methods[instance] = method
163
+ references << method # Avoid introducing cyclic dependency due to the method's dependency on self
164
+ method
165
+ end
166
+
167
+ def configure
168
+ method(:void, :destroy, { target: lvalue }, constraint: -> { destructible? }).configure do
169
+ header %{
170
+ @brief Destroy existing value
171
+
172
+ @param[out] target value to be destroyed
173
+
174
+ This function destroys the value previously constructed with any constructor.
175
+ It involves freeing allocated memory and destroying the constituent values with the respective destructors.
176
+
177
+ It is an error to use the value after call to this function (`*target` is considered to contain garbage afterwards).
178
+
179
+ @since 2.0
180
+ }
181
+ end
182
+ method(:void, :create, { target: lvalue }, instance: :default_create, constraint: -> { default_constructible? }).configure do
183
+ header %{
184
+ @brief Create a new value
185
+
186
+ @param[out] target value to be created
187
+
188
+ This function constructs the value with parameterless constructor.
189
+
190
+ Previous contents of `*target` is overwritten.
191
+
192
+ Once constructed, the value is to be destroyed with @ref #{destroy}.
193
+
194
+ @since 2.0
195
+ }
196
+ end
197
+ method(:void, :copy, { target: lvalue, source: const_rvalue }, constraint: -> { copyable? }).configure do
198
+ header %{
199
+ @brief Create a copy of source value
200
+
201
+ @param[out] target value to be created
202
+ @param[in] source value to be cloned
203
+
204
+ This function is meant to an independent copy (a clone) of `*source` value in place of `*target`.
205
+
206
+ Previous contents of `*target` is overwritten.
207
+
208
+ Once constructed, the value is to be destroyed with @ref #{destroy}.
209
+
210
+ @since 2.0
211
+ }
212
+ end
213
+ method(:int, :equal, { left: const_rvalue, right: const_rvalue }, constraint: -> { comparable? }).configure do
214
+ header %{
215
+ @brief Perform equality testing of two values
216
+
217
+ @param[in] left value to test for equality
218
+ @param[in] right value to test for equality
219
+
220
+ @return non-zero if values are considered equal and zero otherwise
221
+
222
+ This function returns a non-zero value if specified values are considered equal and zero value otherwise.
223
+ Normally the values' contents are considered on equality testing.
224
+
225
+ @since 2.0
226
+ }
227
+ end
228
+ method(:int, :compare, { left: const_rvalue, right: const_rvalue }, constraint: -> { orderable? }).configure do
229
+ header %{
230
+ @brief Compute relative ordering of two values
231
+
232
+ @param[in] left value to order
233
+ @param[in] right value to order
234
+
235
+ @return negative, positive or zero value depending on comparison of the specified values
236
+
237
+ This function returns negative value if `left` precedes `right`, positive value if `left` follows `right` and zero if both values are considered equal.
238
+
239
+ Normally the values' contents are considered on comparison.
240
+
241
+ This function is in general independent to but is expected to be consistent with @ref #{equal} function.
242
+
243
+ @since 2.0
244
+ }
245
+ end
246
+ method(:size_t, :hash_code, { target: const_rvalue }, constraint: -> { hashable? } ).configure do
247
+ header %{
248
+ @brief Compute hash code
249
+
250
+ @param[in] target value to compute hash code for
251
+
252
+ @return hash code
253
+
254
+ This function computes a hash code which reflects the value's contents in some way,
255
+ that is two values considered equal must yield identical hash codes.
256
+ Two different values may or may not yield identical hash codes, however.
257
+
258
+ @since 2.0
259
+ }
260
+ end
261
+ end
262
+
263
+ end # Composite
264
+
265
+
266
+ # Type-bound C side function
267
+ class Composite::Method < Function
268
+
269
+ attr_reader :type
270
+
271
+ def initialize(type, result, name, parameters, **kws)
272
+ @type = type
273
+ super(result.to_value, self.type.identifier(name), parameters, **kws)
274
+ dependencies << self.type << self.result.to_type
275
+ # TODO register parameters' types as dependencies
276
+ end
277
+
278
+ def method_missing(meth, *args)
279
+ if parameters.has_key?(meth) then parameters[meth]
280
+ elsif type.respond_to?(meth) then type.send(meth, *args)
281
+ else meth
282
+ end
283
+ end
284
+
285
+ private
286
+
287
+ def render_function_header(stream)
288
+ if public?
289
+ stream << %{
290
+ /**
291
+ #{type.ingroup}
292
+ #{@header}
293
+ */
294
+ }
295
+ end
296
+ end
297
+
298
+ def render_declaration_specifier(stream)
299
+ stream << (inline? ? 'AUTOC_INLINE ' : 'AUTOC_EXTERN ')
300
+ end
301
+
302
+ def render_implementation(stream)
303
+ render_function_definition(stream) if live? && !inline?
304
+ end
305
+
306
+ end # Method
307
+
308
+
309
+ Composite::DEFINITIONS = Code.new(
310
+ interface: %{
311
+ #ifndef AUTOC_INLINE
312
+ #if defined(__cplusplus)
313
+ #define AUTOC_INLINE inline
314
+ #elif defined(__clang__)
315
+ #define AUTOC_INLINE static __inline __attribute__((unused))
316
+ #elif __STDC_VERSION__ >= 199901L
317
+ #define AUTOC_INLINE static inline
318
+ #else
319
+ #define AUTOC_INLINE static __inline
320
+ #endif
321
+ #endif
322
+ #ifndef AUTOC_EXTERN
323
+ #ifdef __cplusplus
324
+ #define AUTOC_EXTERN extern "C"
325
+ #else
326
+ #define AUTOC_EXTERN extern
327
+ #endif
328
+ #endif
329
+ }
330
+ )
331
+
332
+
333
+ end