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,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