Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca-c-api.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 https://github.com/lrleon/Aleph-w
6
7 This file is part of Aleph-w library
8
9 Copyright (c) 2002-2026 Leandro Rabindranath Leon
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28*/
29
39#define ALEPH_CA_C_API_BUILD 1
40#include "ca-c-api.h"
41
42#include <new>
43#include <string>
44
45#include <ca-engine-utils.H>
46#include <tpl_ca_engine.H>
47#include <tpl_ca_lattice.H>
48#include <tpl_ca_neighborhood.H>
49#include <tpl_ca_rule.H>
50#include <tpl_ca_storage.H>
51
52using namespace Aleph;
53using namespace Aleph::CA;
54
55namespace
56{
57
58// Thread-local last-error state.
59thread_local int g_last_error = ALEPH_CA_OK;
60thread_local std::string g_last_message = "";
61
62void set_error(int code, const char *msg) noexcept
63{
65 try
66 {
67 g_last_message = msg;
68 }
69 catch (...)
70 {
71 // If even copying the message throws (OOM), leave it empty.
72 }
73}
74
75void clear_error() noexcept
76{
78 g_last_message.clear();
79}
80
81} // namespace
82
83// The opaque engine handle owns one Game-of-Life engine.
88
89extern "C"
90{
91
93{
94 return (static_cast<uint32_t>(ALEPH_CA_API_VERSION_MAJOR) << 16)
96}
97
99{
100 return g_last_error;
101}
102
104{
105 return g_last_message.c_str();
106}
107
109{
110 clear_error();
111 if (rows == 0 or cols == 0)
112 {
113 set_error(ALEPH_CA_ERR_RANGE, "create_gol_engine: rows and cols must be > 0");
114 return nullptr;
115 }
116 try
117 {
118 auto *handle = new aleph_ca_engine{
119 make_gol_engine(static_cast<ca_size_t>(rows),
120 static_cast<ca_size_t>(cols))};
121 return handle;
122 }
123 catch (const std::bad_alloc &)
124 {
125 set_error(ALEPH_CA_ERR_ALLOC, "create_gol_engine: out of memory");
126 }
127 catch (const std::exception &e)
128 {
130 }
131 catch (...)
132 {
133 set_error(ALEPH_CA_ERR_INTERNAL, "create_gol_engine: unknown error");
134 }
135 return nullptr;
136}
137
139{
140 delete engine; // delete nullptr is a no-op
141}
142
144 size_t *cols)
145{
146 clear_error();
147 if (engine == nullptr or rows == nullptr or cols == nullptr)
148 {
149 set_error(ALEPH_CA_ERR_NULL, "extents: NULL argument");
150 return ALEPH_CA_ERR_NULL;
151 }
152 *rows = static_cast<size_t>(engine->engine.frame().size(0));
153 *cols = static_cast<size_t>(engine->engine.frame().size(1));
154 return ALEPH_CA_OK;
155}
156
159{
160 clear_error();
161 if (engine == nullptr)
162 {
163 set_error(ALEPH_CA_ERR_NULL, "set_cell: NULL engine");
164 return ALEPH_CA_ERR_NULL;
165 }
166 auto &frame = engine->engine.write_lattice();
167 if (row >= static_cast<size_t>(frame.size(0))
168 or col >= static_cast<size_t>(frame.size(1)))
169 {
170 set_error(ALEPH_CA_ERR_RANGE, "set_cell: coordinate out of range");
171 return ALEPH_CA_ERR_RANGE;
172 }
173 frame.set({static_cast<ca_index_t>(row), static_cast<ca_index_t>(col)},
174 value != 0 ? 1 : 0);
175 return ALEPH_CA_OK;
176}
177
179 size_t col, int32_t *out)
180{
181 clear_error();
182 if (engine == nullptr or out == nullptr)
183 {
184 set_error(ALEPH_CA_ERR_NULL, "get_cell: NULL argument");
185 return ALEPH_CA_ERR_NULL;
186 }
187 const auto &frame = engine->engine.frame();
188 if (row >= static_cast<size_t>(frame.size(0))
189 or col >= static_cast<size_t>(frame.size(1)))
190 {
191 set_error(ALEPH_CA_ERR_RANGE, "get_cell: coordinate out of range");
192 return ALEPH_CA_ERR_RANGE;
193 }
194 *out = static_cast<int32_t>(
195 frame.at({static_cast<ca_index_t>(row), static_cast<ca_index_t>(col)}));
196 return ALEPH_CA_OK;
197}
198
200{
201 clear_error();
202 if (engine == nullptr)
203 {
204 set_error(ALEPH_CA_ERR_NULL, "step: NULL engine");
205 return ALEPH_CA_ERR_NULL;
206 }
207 try
208 {
209 engine->engine.step();
210 return ALEPH_CA_OK;
211 }
212 catch (const std::exception &e)
213 {
215 }
216 catch (...)
217 {
218 set_error(ALEPH_CA_ERR_INTERNAL, "step: unknown error");
219 }
221}
222
224{
225 clear_error();
226 if (engine == nullptr)
227 {
228 set_error(ALEPH_CA_ERR_NULL, "run: NULL engine");
229 return ALEPH_CA_ERR_NULL;
230 }
231 try
232 {
233 engine->engine.run(static_cast<std::size_t>(steps));
234 return ALEPH_CA_OK;
235 }
236 catch (const std::exception &e)
237 {
239 }
240 catch (...)
241 {
242 set_error(ALEPH_CA_ERR_INTERNAL, "run: unknown error");
243 }
245}
246
248 size_t out_len)
249{
250 clear_error();
251 if (engine == nullptr or out == nullptr)
252 {
253 set_error(ALEPH_CA_ERR_NULL, "copy_frame: NULL argument");
254 return ALEPH_CA_ERR_NULL;
255 }
256 const auto &frame = engine->engine.frame();
257 const size_t rows = static_cast<size_t>(frame.size(0));
258 const size_t cols = static_cast<size_t>(frame.size(1));
259 if (out_len < rows * cols)
260 {
261 set_error(ALEPH_CA_ERR_RANGE, "copy_frame: out buffer too small");
262 return ALEPH_CA_ERR_RANGE;
263 }
264 size_t k = 0;
265 for (size_t i = 0; i < rows; ++i)
266 for (size_t j = 0; j < cols; ++j)
267 out[k++] = static_cast<int32_t>(
268 frame.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}));
269 return ALEPH_CA_OK;
270}
271
273{
274 if (engine == nullptr)
275 return 0;
276 return static_cast<size_t>(engine->engine.steps_run());
277}
278
279} // extern "C"
aleph_ca_engine_t * aleph_ca_create_gol_engine_v1(size_t rows, size_t cols)
Definition ca-c-api.cc:108
int aleph_ca_copy_frame_v1(const aleph_ca_engine_t *engine, int32_t *out, size_t out_len)
Definition ca-c-api.cc:247
void aleph_ca_destroy_engine_v1(aleph_ca_engine_t *engine)
Definition ca-c-api.cc:138
int aleph_ca_extents_v1(const aleph_ca_engine_t *engine, size_t *rows, size_t *cols)
Definition ca-c-api.cc:143
int aleph_ca_step_v1(aleph_ca_engine_t *engine)
Definition ca-c-api.cc:199
int aleph_ca_set_cell_v1(aleph_ca_engine_t *engine, size_t row, size_t col, int32_t value)
Definition ca-c-api.cc:157
int aleph_ca_run_v1(aleph_ca_engine_t *engine, size_t steps)
Definition ca-c-api.cc:223
int aleph_ca_last_error_v1(void)
Definition ca-c-api.cc:98
const char * aleph_ca_error_message_v1(void)
Definition ca-c-api.cc:103
int aleph_ca_get_cell_v1(const aleph_ca_engine_t *engine, size_t row, size_t col, int32_t *out)
Definition ca-c-api.cc:178
size_t aleph_ca_steps_run_v1(const aleph_ca_engine_t *engine)
Definition ca-c-api.cc:272
uint32_t aleph_ca_api_version_v1(void)
Definition ca-c-api.cc:92
int32_t size_t out_len
Definition ca-c-api.h:131
size_t steps
Definition ca-c-api.h:126
size_t size_t int32_t value
Definition ca-c-api.h:116
size_t size_t int32_t * out
Definition ca-c-api.h:120
#define ALEPH_CA_API_VERSION_MAJOR
Definition ca-c-api.h:68
size_t row
Definition ca-c-api.h:115
size_t * rows
Definition ca-c-api.h:112
size_t size_t col
Definition ca-c-api.h:116
@ ALEPH_CA_ERR_ALLOC
Definition ca-c-api.h:77
@ ALEPH_CA_ERR_NULL
Definition ca-c-api.h:75
@ ALEPH_CA_OK
Definition ca-c-api.h:74
@ ALEPH_CA_ERR_INTERNAL
Definition ca-c-api.h:78
@ ALEPH_CA_ERR_RANGE
Definition ca-c-api.h:76
size_t cols
Definition ca-c-api.h:105
#define ALEPH_CA_API_VERSION_MINOR
Definition ca-c-api.h:69
Convenience builders for the Phase 3 synchronous engine.
Synchronous double-buffered engine.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
Game_Of_Life_Engine make_gol_engine(ca_size_t rows, ca_size_t cols)
Build a Conway's Game of Life engine of the given shape.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
Game_Of_Life_Engine engine
Definition ca-c-api.cc:86
static int * k
static mt19937 engine
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Rule mechanisms for Aleph::CA.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).