autoc 1.4 → 2.0.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.
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,247 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'autoc/std'
5
+ require 'autoc/composite'
6
+
7
+
8
+ module AutoC
9
+
10
+
11
+ using STD::Coercions
12
+
13
+
14
+ # C struct wrapper with managed fields
15
+ class Record < Composite
16
+
17
+ attr_reader :fields
18
+
19
+ def default_constructible? = fields.values.all? { |t| t.default_constructible? }
20
+ def custom_constructible? = fields.values.all? { |t| t.copyable? }
21
+ def destructible? = fields.values.any? { |t| t.destructible? }
22
+ def comparable? = fields.values.all? { |t| t.comparable? }
23
+ def copyable? = fields.values.all? { |t| t.copyable? }
24
+ def hashable? = fields.values.all? { |t| t.hashable? }
25
+ def orderable? = false
26
+
27
+ def initialize(type, fields, visibility: :public, profile: :blackbox, **kws)
28
+ super(type, visibility:, **kws)
29
+ setup_profile(profile)
30
+ setup_fields(fields)
31
+ end
32
+
33
+ def render_interface(stream)
34
+ if public?
35
+ stream << %{
36
+ /**
37
+ #{defgroup}
38
+
39
+ @brief Value type wrapper of the C struct
40
+
41
+ @since 2.0
42
+ */
43
+ }
44
+ if @opaque
45
+ stream << %{
46
+ /**
47
+ #{ingroup}
48
+
49
+ @brief Opaque struct holding state of the record
50
+
51
+ @since 2.0
52
+ */
53
+ }
54
+ else
55
+ stream << %{
56
+ /**
57
+ #{ingroup}
58
+
59
+ @brief Open struct holding state of the record
60
+
61
+ The struct's fields are directly acessible.
62
+ However, care must be taken when modifying the struct's contents directly
63
+ as it may break the contract(s) of certain (namely, hash- and tree-based) containers.
64
+
65
+ For the safety reasons these fields should be generally treated read-only.
66
+
67
+ @since 2.0
68
+ */
69
+ }
70
+ end
71
+ else
72
+ stream << PRIVATE
73
+ end
74
+ stream << 'typedef struct {'
75
+ fields.each { |name, type| stream << field_declaration(type, name) }
76
+ stream << "} #{signature};"
77
+ end
78
+
79
+ def type_tag = "#{signature}<#{fields.values.join(',')}>"
80
+
81
+ private
82
+
83
+ # @private
84
+ def setup_fields(fields)
85
+ @fields = fields.transform_values { |type| type.to_type }
86
+ self.fields.each_value { |type| dependencies << type }
87
+ end
88
+
89
+ # @private
90
+ def setup_profile(profile)
91
+ case profile
92
+ when :blackbox
93
+ #@inline_methods = false
94
+ @omit_accessors = false
95
+ @opaque = true
96
+ when :glassbox
97
+ #@inline_methods = true
98
+ @omit_accessors = true
99
+ @opaque = false
100
+ else raise "unsupported profile #{profile}"
101
+ end
102
+ end
103
+
104
+ # @private
105
+ def field_variable(opt)
106
+ if opt.is_a?(::Hash)
107
+ obj, name = opt.first
108
+ "#{obj}->#{name}"
109
+ else
110
+ opt
111
+ end
112
+ end
113
+
114
+ # @private
115
+ def field_declaration(type, name)
116
+ s = "#{type} #{field_variable(name)};"
117
+ s += @opaque ? '/**< @private */' : "/**< @brief Field of type #{type} */"
118
+ s
119
+ end
120
+
121
+ def configure
122
+ super
123
+ ### set
124
+ params = []
125
+ docs = []
126
+ args = { target: lvalue }
127
+ fields.each do |name, type|
128
+ formal = "#{name}".to_sym
129
+ value = type.const_rvalue
130
+ params << [name, Parameter.new(value, formal)]
131
+ args[formal] = value
132
+ docs << "@param[in] #{formal} `#{name}` field initializer of type @ref #{type}"
133
+ end
134
+ method(:void, :create_set, args, instance: :custom_create).configure do
135
+ _code = 'assert(target);'
136
+ params.each do |field, parameter|
137
+ _code += parameter.value.type.copy.("target->#{field}", parameter) + ';'
138
+ end
139
+ code _code
140
+ header %{
141
+ @brief Initialize record
142
+
143
+ @param[in] target record to create
144
+
145
+ This function initializes new record's fields with copies of respective arguments.
146
+
147
+ Previous contents of `*target` is overwritten.
148
+
149
+ @since 2.0
150
+ }
151
+ end
152
+ ### default_create
153
+ _code = 'assert(target);'
154
+ fields.each { |name, type| _code += type.default_create.("target->#{name}") + ';' }
155
+ default_create.configure { code _code }
156
+ ### destroy
157
+ _code = 'assert(target);'
158
+ fields.each { |name, type| _code += type.destroy.("target->#{name}") + ';' if type.destructible? }
159
+ destroy.configure { code _code }
160
+ ### copy
161
+ _code = 'assert(target); assert(source);'
162
+ fields.each { |name, type| _code += type.copy.("target->#{name}", "source->#{name}") + ';' }
163
+ copy.configure { code _code }
164
+ ### equal
165
+ _code = 'assert(left); assert(right);'
166
+ _code += 'return ' + fields.collect { |name, type| type.equal.("left->#{name}", "right->#{name}") }.join(' && ') + ';'
167
+ equal.configure { code _code }
168
+ ### hash_code
169
+ _code = %{
170
+ #{hasher.to_s} hash;
171
+ size_t result;
172
+ assert(target);
173
+ #{hasher.create(:hash)};
174
+ }
175
+ fields.each { |name, type| _code += hasher.update(:hash, type.hash_code.("target->#{name}")) + ';' if type.hashable? }
176
+ _code += %{
177
+ result = #{hasher.result(:hash)};
178
+ #{hasher.destroy(hash)};
179
+ return result;
180
+ }
181
+ hash_code.configure { code _code }
182
+ ###
183
+ unless @omit_accessors
184
+ fields.each do |name, type|
185
+ method(type.const_lvalue, "view_#{name}", { target: const_lvalue }, inline: true ).configure do
186
+ code %{
187
+ assert(target);
188
+ return &target->#{name};
189
+ }
190
+ header %{
191
+ @brief Get a view of the field #{name}
192
+
193
+ @param[in] target record to query
194
+ @return a view of the value of type #{type} contained in field #{name}
195
+
196
+ This function is used to get a constant reference (in form of the C pointer) to the value in field #{name} contained in `target`.
197
+
198
+ @since 2.0
199
+ }
200
+ end
201
+ if type.copyable?
202
+ method(type, "get_#{name}", { target: const_rvalue } ).configure do
203
+ code %{
204
+ #{type} result;
205
+ assert(target);
206
+ #{type.copy.(:result, "target->#{name}")};
207
+ return result;
208
+ }
209
+ header %{
210
+ @brief Get a copy of the value of field #{name}
211
+
212
+ @param[in] target record to query
213
+ @return a copy of the value of type #{type} contained in field #{name}
214
+
215
+ This function is used to get a copy the value in field #{name} contained in `target`.
216
+
217
+ @since 2.0
218
+ }
219
+ end
220
+ method(:void, "set_#{name}", { target: rvalue, name.to_sym => type.const_rvalue } ).configure do
221
+ code %{
222
+ assert(target);
223
+ #{type.destroy.("target->#{name}") if type.destructible?};
224
+ #{type.copy.("target->#{name}", name)};
225
+ }
226
+ header %{
227
+ @brief Set value of field #{name}
228
+
229
+ @param[in] target record to modify
230
+ @param[in] #{name} value to initalize field #{name} with
231
+
232
+ This function sets the field #{name} to contain a copy of specified value.
233
+
234
+ Previous field's contents is destroyed the respective destructor.
235
+
236
+ @since 2.0
237
+ }
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ end # Record
245
+
246
+
247
+ end
@@ -0,0 +1,117 @@
1
+ require 'autoc'
2
+ require 'autoc/module'
3
+
4
+ main = AutoC::Code.new interface: %{
5
+ /**
6
+ @mainpage AutoC-generated interface reference version #{AutoC::VERSION}
7
+
8
+ @section intro Introduction
9
+
10
+ The AutoC provides a set of source code generators for widely-known containers such as vector, list, set, map etc.
11
+ The result is similar to that of the C++ STL template classes which generate the specialized versions of
12
+ the generic containers but in this case in ***pure C language***.
13
+
14
+ @section start Kick start
15
+
16
+ Suppose one needs to have a pure C implementation of the set of integer values (`std::unordered_set<int>` in C++ terms).
17
+ Such code may be obtained with AutoC by executing the following instructions.
18
+
19
+ 1. Install the AutoC gem
20
+ ```shell
21
+ > gem install autoc
22
+ ```
23
+ 2. Create the type implementation generator in file `test.rb`
24
+ ```ruby
25
+ require 'autoc/hash_set'
26
+ AutoC::Module.render(:test) do |m|
27
+ m << AutoC::HashSet.new(:IntSet, :int)
28
+ end
29
+ ```
30
+ 3. Generate the type implementation
31
+ ```shell
32
+ > ruby test.rb
33
+ ```
34
+ 4. Extract the code-specific auto-generated interface documentation
35
+ ```shell
36
+ > doxygen .
37
+ ```
38
+ 5. Create a test code in file `test.c`
39
+ ```c
40
+ #include <stdio.h>
41
+ #include "test_auto.h"
42
+ int main(int argc, char** argv) {
43
+ IntSet set;
44
+ IntSetCreate(&set);
45
+ IntSetPut(&set, 1);
46
+ IntSetPut(&set, 0);
47
+ IntSetPut(&set, 1);
48
+ printf("size = %d\\n", IntSetSize(&set));
49
+ for(IntSetRange r = IntSetRangeNew(&set); !IntSetRangeEmpty(&r); IntSetRangePopFront(&r)) {
50
+ printf("%d\\n", IntSetRangeTakeFront(&r));
51
+ }
52
+ IntSetDestroy(&set);
53
+ }
54
+ ```
55
+ 6. Compile the test executable
56
+ ```shell
57
+ > cc -g -o test test.c test_auto.c
58
+ ```
59
+ 7. Perform a test run with Valgrind
60
+ ```shell
61
+ > valgrind ./test
62
+ ```
63
+ */
64
+ }
65
+
66
+ require_relative 'generic_value'
67
+
68
+ # @private
69
+ class DocsValue < GenericValue
70
+ attr_reader :description
71
+ def initialize(type, desc)
72
+ super(type)
73
+ @description = desc
74
+ end
75
+ end
76
+
77
+ A = DocsValue.new(:A, 'Generic value type')
78
+ B = DocsValue.new(:B, 'Generic value type')
79
+ T = DocsValue.new(:T, 'Generic value type')
80
+ K = DocsValue.new(:K, 'Generic hashable value type')
81
+
82
+ # @private
83
+ class Docs < AutoC::Module
84
+ def initialize(*args, **kws)
85
+ super
86
+ class << header
87
+ def file_name = 'autoc.h'
88
+ end
89
+ end
90
+ def render
91
+ distribute_entities
92
+ header.render
93
+ end
94
+ end
95
+
96
+ require 'autoc/cstring'
97
+
98
+ require 'autoc/list'
99
+ require 'autoc/vector'
100
+ require 'autoc/hash_set'
101
+ require 'autoc/hash_map'
102
+
103
+ require 'autoc/box'
104
+ require 'autoc/record'
105
+
106
+ m = Docs.new(:autoc)
107
+
108
+ m << main
109
+ m << AutoC::CString.new
110
+ m << AutoC::Vector.new(:Vector, T)
111
+ m << AutoC::List.new(:List, T)
112
+ m << AutoC::HashSet.new(:HashSet, T)
113
+ m << AutoC::HashMap.new(:HashMap, T, K)
114
+ m << AutoC::Box.new(:Box, { a: A, b: B })
115
+ m << AutoC::Record.new(:Record, { a: A, b: B })
116
+
117
+ m.render
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require 'autoc/std'
5
+ require 'autoc/composite'
6
+
7
+
8
+ # Full-fledged value type equipped with dynamic memory management
9
+ # useful for testing & documentation purposes
10
+ class GenericValue < AutoC::Composite
11
+
12
+ using AutoC::STD::Coercions
13
+
14
+ def render_interface(stream)
15
+ super
16
+ stream << %{
17
+ /**
18
+ @brief #{description}
19
+ */
20
+ typedef struct {
21
+ int* value; /**< @private */
22
+ } #{signature};
23
+ }
24
+ end
25
+
26
+ def rvalue = @rv ||= AutoC::Value.new(self, reference: true)
27
+
28
+ def lvalue = @lv ||= AutoC::Value.new(self, reference: true)
29
+
30
+ def const_rvalue = @crv ||= AutoC::Value.new(self, constant: true)
31
+
32
+ def const_lvalue = @clv ||= AutoC::Value.new(self, constant: true, reference: true)
33
+
34
+ private
35
+
36
+ def configure
37
+ super
38
+ method(:void, :set, { target: lvalue, value: :int.const_rvalue }, instance: :custom_create).configure do
39
+ code %{
40
+ #{default_create.(target)};
41
+ *target->value = value;
42
+ }
43
+ end
44
+ method(:int, :get, { target: const_rvalue }).configure do
45
+ code %{
46
+ return *target.value;
47
+ }
48
+ end
49
+ default_create.configure do
50
+ code %{
51
+ assert(target);
52
+ target->value = #{memory.allocate('int')};
53
+ *target->value = 0;
54
+ }
55
+ end
56
+ destroy.configure do
57
+ code %{
58
+ assert(target);
59
+ #{memory.free('target->value')};
60
+ }
61
+ end
62
+ copy.configure do
63
+ code %{
64
+ assert(target);
65
+ #{default_create}(target);
66
+ *target->value = *source.value;
67
+ }
68
+ end
69
+ equal.configure do
70
+ code %{
71
+ return *left.value == *right.value;
72
+ }
73
+ end
74
+ compare.configure do
75
+ code %{
76
+ return *left.value < *right.value ? -1 : (*left.value > *right.value ? +1 : 0);
77
+ }
78
+ end
79
+ hash_code.configure do
80
+ code %{
81
+ return *target.value;
82
+ }
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,75 @@
1
+ ###
2
+ def project_c(project)
3
+ <<END
4
+ #include "_#{project}_auto.h"
5
+
6
+ #include <stdio.h>
7
+
8
+ int main(int argc, char **argv) {
9
+ CString msg;
10
+ CStringCreateFormat(&msg, "Hello %s!\\n", "#{project}");
11
+ printf(msg);
12
+ CStringDestroy(&msg);
13
+ return 0;
14
+ }
15
+ END
16
+ end
17
+
18
+
19
+ ###
20
+ def cmakelists_txt(project)
21
+ <<END
22
+ project(#{project})
23
+
24
+ cmake_minimum_required(VERSION 3.15)
25
+
26
+ set(AUTOC_MODULE_NAME _${PROJECT_NAME})
27
+ set(AUTOC_MODULE_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.rb)
28
+
29
+ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
30
+
31
+ include(AutoC)
32
+
33
+ add_autoc_module(
34
+ ${AUTOC_MODULE_NAME}
35
+ DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
36
+ MAIN_DEPENDENCY ${AUTOC_MODULE_SOURCE}
37
+ COMMAND ${Ruby_EXECUTABLE} ${AUTOC_MODULE_SOURCE}
38
+ )
39
+
40
+ add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c)
41
+ target_link_libraries(${PROJECT_NAME} ${AUTOC_MODULE_NAME})
42
+ END
43
+ end
44
+
45
+
46
+ ###
47
+ def project_rb(project)
48
+ <<END
49
+ require 'autoc/module'
50
+ require 'autoc/cstring'
51
+
52
+ m = AutoC::Module.render(:_#{project}) do |m|
53
+ m << AutoC::CString.new
54
+ end
55
+
56
+ require 'autoc/cmake'
57
+
58
+ AutoC::CMake.render(m)
59
+ END
60
+ end
61
+
62
+
63
+ if ARGV.size < 1
64
+ $stderr << "usage: ruby -r autoc/scaffold -e project project_name\n"
65
+ exit 1
66
+ end
67
+
68
+ project = ARGV[0]
69
+
70
+ require 'fileutils'
71
+ FileUtils.copy_entry(File.dirname(__FILE__)+'/../../../cmake', 'cmake')
72
+
73
+ File.write('CMakeLists.txt', cmakelists_txt(project))
74
+ File.write("#{project}.rb", project_rb(project))
75
+ File.write("#{project}.c", project_c(project))
@@ -0,0 +1,113 @@
1
+ require 'autoc/cstring'
2
+
3
+ CString = type_test(AutoC::CString, :CString) do
4
+
5
+ ###
6
+
7
+ setup %{
8
+ #{self} s;
9
+ }
10
+
11
+ cleanup %{
12
+ #{destroy.(:s)};
13
+ }
14
+
15
+ test :create_empty, %{
16
+ #{custom_create.(:s, %{""})};
17
+ TEST_EQUAL( #{size.(:s)}, 0 );
18
+ TEST_TRUE( #{empty}(s) );
19
+ }
20
+
21
+ test :create_non_empty, %{
22
+ #{custom_create.(:s, %{"hello"})};
23
+ TEST_EQUAL( #{size.(:s)}, 5 );
24
+ }
25
+
26
+ test :format_empty, %{
27
+ TEST_TRUE( #{create_format.(:s, %{""})} );
28
+ TEST_TRUE( #{empty}(s) );
29
+ }
30
+
31
+ test :format_empty_params, %{
32
+ TEST_TRUE( #{create_format.(:s, %{"hello"})} );
33
+ TEST_TRUE( #{equal}(s, "hello") );
34
+ TEST_FALSE( #{empty}(s) );
35
+ }
36
+
37
+ test :format_int, %{
38
+ TEST_TRUE( #{create_format.(:s, %{"hello%d"}, -3)} );
39
+ TEST_TRUE( #{equal}("hello-3", s) );
40
+ }
41
+
42
+ test :equal_cstr, %{
43
+ #{custom_create.(:s, %{"hello"})};
44
+ TEST_TRUE( #{equal.(:s, %{"hello"})} );
45
+ }
46
+
47
+ test :compare_cstr, %{
48
+ #{custom_create.(:s, %{"hello"})};
49
+ TEST_FALSE( #{equal.(%{"hello1"}, :s)} );
50
+ TEST_FALSE( #{equal.(:s, %{"hello1"})} );
51
+ TEST_TRUE( #{compare.(:s, %{"hello1"})} < 0 );
52
+ TEST_TRUE( #{compare.(%{"hello1"}, :s)} > 0 );
53
+ }
54
+
55
+ ###
56
+
57
+ setup %{
58
+ #{self} s1, s2;
59
+ }
60
+
61
+ cleanup %{
62
+ #{destroy.(:s1)};
63
+ #{destroy.(:s2)};
64
+ }
65
+
66
+ test :compare_equal, %{
67
+ #{custom_create.(:s1, %{"hello"})};
68
+ #{custom_create.(:s2, %{"hello"})};
69
+ TEST_TRUE( #{equal.(:s1, :s2)} );
70
+ TEST_EQUAL( #{compare.(:s1, :s2)}, 0 );
71
+ TEST_EQUAL( #{hash_code.(:s1)}, #{hash_code.(:s2)} );
72
+ }
73
+
74
+ test :compare_non_equal, %{
75
+ #{custom_create.(:s1, %{"hello1"})};
76
+ #{custom_create.(:s2, %{"hello2"})};
77
+ TEST_FALSE( #{equal.(:s1, :s2)} );
78
+ TEST_FALSE( #{equal.(:s2, :s1)} );
79
+ TEST_TRUE( #{compare.(:s1, :s2)} < 0 );
80
+ TEST_TRUE( #{compare.(:s2, :s1)} > 0 );
81
+ }
82
+
83
+ ###
84
+
85
+ setup %{
86
+ #{self} s;
87
+ #{custom_create.(:s, %{"hello"})};
88
+ }
89
+
90
+ cleanup %{
91
+ #{destroy.(:s)};
92
+ }
93
+
94
+ test :char_access, %{
95
+ TEST_EQUAL( #{get.(:s, 0)}, 'h' );
96
+ TEST_EQUAL( *#{view}(s, 4), 'o' );
97
+ }
98
+
99
+ test :range_access, %{
100
+ #{range} r = #{range.new.(:s)};
101
+ TEST_EQUAL( #{size}(s), 5 );
102
+ TEST_EQUAL( #{range.size}(&r), #{size}(s) );
103
+ TEST_EQUAL( #{range.take_front}(&r), 'h' );
104
+ TEST_EQUAL( *#{range.view_back}(&r), 'o' );
105
+ #{range.pop_front}(&r);
106
+ TEST_EQUAL( *#{range.view_front}(&r), 'e' );
107
+ TEST_EQUAL( #{range.size}(&r), #{size}(s)-1 );
108
+ #{range.pop_back}(&r);
109
+ TEST_EQUAL( #{range.take_back}(&r), 'l' );
110
+ TEST_EQUAL( #{range.size}(&r), #{size}(s)-2 );
111
+ }
112
+
113
+ end
@@ -0,0 +1,35 @@
1
+ require 'autoc/hash_set'
2
+
3
+ require_relative 'test_cstring'
4
+
5
+ type_test(AutoC::HashSet, :CStringHashSet, CString) do
6
+
7
+ ###
8
+
9
+ setup %{
10
+ #{self} t;
11
+ }
12
+
13
+ cleanup %{
14
+ #{destroy}(&t);
15
+ }
16
+
17
+ test :create_default, %{
18
+ #{default_create}(&t);
19
+ TEST_EQUAL( #{size}(&t), 0 );
20
+ }
21
+
22
+ test :create_custom, %{
23
+ #{create_capacity}(&t, 1024);
24
+ TEST_EQUAL( #{size}(&t), 0 );
25
+ }
26
+
27
+ test :put, %{
28
+ #{default_create}(&t);
29
+ #{put}(&t, "kitty");
30
+ #{put}(&t, "hello");
31
+ #{put}(&t, "kitty");
32
+ TEST_EQUAL( #{size}(&t), 2 );
33
+ }
34
+
35
+ end
@@ -0,0 +1,22 @@
1
+ require 'autoc/box'
2
+ require_relative 'test_int_vector'
3
+
4
+ type_test(AutoC::Box, :IntBox, { number: :int, numbers: IntVector }) do
5
+
6
+ ###
7
+
8
+ setup %{
9
+ #{self} t;
10
+ #{default_create.(:t)};
11
+ }
12
+
13
+ cleanup %{
14
+ #{destroy.(:t)};
15
+ }
16
+
17
+ test :create_empty, %{
18
+ #{purge.(:t)};
19
+ TEST_FALSE( #{tag.(:t)} );
20
+ }
21
+
22
+ end