diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md index bc0a6bf1b884..7a250edf7b59 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/README.md @@ -106,6 +106,109 @@ console.log( headerDir ); +#### STDLIB_MATH_BASE_NAPI_MODULE_CCCC_C( fcn ) + +Macro for registering a Node-API module exporting an interface for invoking a quaternary function accepting and returning single-precision complex floating-point numbers. + +```c +#include "stdlib/complex/float32/ctor.h" +#include "stdlib/complex/float32/reim.h" + +static stdlib_complex64_t add( const stdlib_complex64_t w, const stdlib_complex64_t x, const stdlib_complex64_t y, const stdlib_complex64_t z ) { + float wre; + float wim; + float xre; + float xim; + float yre; + float yim; + float zre; + float zim; + float re; + float im; + + stdlib_complex64_reim( w, &wre, &wim ); + stdlib_complex64_reim( x, &xre, &xim ); + stdlib_complex64_reim( y, &yre, &yim ); + stdlib_complex64_reim( z, &zre, &zim ); + + re = wre + xre + yre + zre; + im = wim + xim + yim + zim; + + return stdlib_complex64( re, im ); +} + +// ... + +// Register a Node-API module: +STDLIB_MATH_BASE_NAPI_MODULE_CCCC_C( add ); +``` + +The macro expects the following arguments: + +- **fcn**: `stdlib_complex64_t (*fcn)( stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t )` quaternary function. + +When used, this macro should be used **instead of** `NAPI_MODULE`. The macro includes `NAPI_MODULE`, thus ensuring Node-API module registration. + +#### stdlib_math_base_napi_cccc_c( env, info, fcn ) + +Invokes a quaternary function accepting and returning single-precision complex floating-point numbers. + +```c +#include "stdlib/complex/float32/ctor.h" +#include "stdlib/complex/float32/reim.h" +#include + +// ... + +static stdlib_complex64_t add( const stdlib_complex64_t w, const stdlib_complex64_t x, const stdlib_complex64_t y, const stdlib_complex64_t z ) { + float wre; + float wim; + float xre; + float xim; + float yre; + float yim; + float zre; + float zim; + float re; + float im; + + stdlib_complex64_reim( w, &wre, &wim ); + stdlib_complex64_reim( x, &xre, &xim ); + stdlib_complex64_reim( y, &yre, &yim ); + stdlib_complex64_reim( z, &zre, &zim ); + + re = wre + xre + yre + zre; + im = wim + xim + yim + zim; + + return stdlib_complex64( re, im ); +} + +// ... + +/** +* Receives JavaScript callback invocation data. +* +* @param env environment under which the function is invoked +* @param info callback data +* @return Node-API value +*/ +napi_value addon( napi_env env, napi_callback_info info ) { + return stdlib_math_base_napi_cccc_c( env, info, add ); +} + +// ... +``` + +The function accepts the following arguments: + +- **env**: `[in] napi_env` environment under which the function is invoked. +- **info**: `[in] napi_callback_info` callback data. +- **fcn**: `[in] stdlib_complex64_t (*fcn)( stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t )` quaternary function. + +```c +void stdlib_math_base_napi_cccc_c( napi_env env, napi_callback_info info, stdlib_complex64_t (*fcn)( stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t ) ); +``` + #### STDLIB_MATH_BASE_NAPI_MODULE_DDDD_D( fcn ) Macro for registering a Node-API module exporting an interface for invoking a quaternary function accepting and returning double-precision floating-point numbers. diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h index 3bce886cc661..dceb9ee85b59 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary.h @@ -20,6 +20,7 @@ #define STDLIB_MATH_BASE_NAPI_QUATERNARY_H // NOTE: keep in alphabetical order... +#include "stdlib/math/base/napi/quaternary/cccc_c.h" #include "stdlib/math/base/napi/quaternary/dddd_d.h" #include "stdlib/math/base/napi/quaternary/diii_d.h" #include "stdlib/math/base/napi/quaternary/ffff_f.h" diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/cccc_c.h b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/cccc_c.h new file mode 100644 index 000000000000..b52a0de901cb --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/include/stdlib/math/base/napi/quaternary/cccc_c.h @@ -0,0 +1,104 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef STDLIB_MATH_BASE_NAPI_QUATERNARY_CCCC_C_H +#define STDLIB_MATH_BASE_NAPI_QUATERNARY_CCCC_C_H + +#include "stdlib/complex/float32/ctor.h" +#include +#include + +/** +* Macro for registering a Node-API module exporting an interface invoking a quaternary function accepting and returning single-precision complex floating-point numbers. +* +* @param fcn quaternary function +* +* @example +* #include "stdlib/complex/float32/ctor.h" +* #include "stdlib/complex/float32/reim.h" +* +* static stdlib_complex64_t add( const stdlib_complex64_t w, const stdlib_complex64_t x, const stdlib_complex64_t y, const stdlib_complex64_t z ) { +* float wre; +* float wim; +* float xre; +* float xim; +* float yre; +* float yim; +* float zre; +* float zim; +* float re; +* float im; +* +* stdlib_complex64_reim( w, &wre, &wim ); +* stdlib_complex64_reim( x, &xre, &xim ); +* stdlib_complex64_reim( y, &yre, &yim ); +* stdlib_complex64_reim( z, &zre, &zim ); +* +* re = wre + xre + yre + zre; +* im = wim + xim + yim + zim; +* +* return stdlib_complex64( re, im ); +* } +* +* // ... +* +* // Register a Node-API module: +* STDLIB_MATH_BASE_NAPI_MODULE_CCCC_C( add ); +*/ +#define STDLIB_MATH_BASE_NAPI_MODULE_CCCC_C( fcn ) \ + static napi_value stdlib_math_base_napi_cccc_c_wrapper( \ + napi_env env, \ + napi_callback_info info \ + ) { \ + return stdlib_math_base_napi_cccc_c( env, info, fcn ); \ + }; \ + static napi_value stdlib_math_base_napi_cccc_c_init( \ + napi_env env, \ + napi_value exports \ + ) { \ + napi_value f; \ + napi_status status = napi_create_function( \ + env, \ + "exports", \ + NAPI_AUTO_LENGTH, \ + stdlib_math_base_napi_cccc_c_wrapper, \ + NULL, \ + &f \ + ); \ + assert( status == napi_ok ); \ + return f; \ + }; \ + NAPI_MODULE( NODE_GYP_MODULE_NAME, stdlib_math_base_napi_cccc_c_init ) + +/* +* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +/** +* Invokes a quaternary function accepting and returning single-precision complex floating-point numbers. +*/ +napi_value stdlib_math_base_napi_cccc_c( napi_env env, napi_callback_info info, stdlib_complex64_t (*fcn)( stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t ) ); + +#ifdef __cplusplus +} +#endif + +#endif // !STDLIB_MATH_BASE_NAPI_QUATERNARY_CCCC_C_H diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json b/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json index 4fd0db80e085..065dfcada76e 100644 --- a/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/manifest.json @@ -25,6 +25,7 @@ "confs": [ { "src": [ + "./src/cccc_c.c", "./src/dddd_d.c", "./src/diii_d.c", "./src/ffff_f.c", @@ -36,6 +37,8 @@ "libraries": [], "libpath": [], "dependencies": [ + "@stdlib/complex/float32/ctor", + "@stdlib/complex/float32/reim", "@stdlib/complex/float64/ctor", "@stdlib/complex/float64/reim" ] diff --git a/lib/node_modules/@stdlib/math/base/napi/quaternary/src/cccc_c.c b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/cccc_c.c new file mode 100644 index 000000000000..4b68588131e3 --- /dev/null +++ b/lib/node_modules/@stdlib/math/base/napi/quaternary/src/cccc_c.c @@ -0,0 +1,281 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "stdlib/math/base/napi/quaternary/cccc_c.h" +#include "stdlib/complex/float32/ctor.h" +#include "stdlib/complex/float32/reim.h" +#include +#include + +/** +* Invokes a quaternary function accepting and returning single-precision complex floating-point numbers. +* +* ## Notes +* +* - This function expects that the callback `info` argument provides access to the following JavaScript arguments: +* +* - `w`: input value. +* - `x`: input value. +* - `y`: input value. +* - `z`: input value. +* +* @param env environment under which the function is invoked +* @param info callback data +* @param fcn quaternary function +* @return function return value as a Node-API complex-like object +*/ +napi_value stdlib_math_base_napi_cccc_c( napi_env env, napi_callback_info info, stdlib_complex64_t (*fcn)( stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t, stdlib_complex64_t ) ) { + napi_status status; + + size_t argc = 4; + napi_value argv[ 4 ]; + status = napi_get_cb_info( env, info, &argc, argv, NULL, NULL ); + assert( status == napi_ok ); + + if ( argc < 4 ) { + status = napi_throw_error( env, NULL, "invalid invocation. Must provide four complex numbers." ); + assert( status == napi_ok ); + return NULL; + } + + bool hprop; + status = napi_has_named_property( env, argv[ 0 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value wre; + status = napi_get_named_property( env, argv[ 0 ], "re", &wre ); + assert( status == napi_ok ); + + napi_valuetype wretype; + status = napi_typeof( env, wre, &wretype ); + assert( status == napi_ok ); + if ( wretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 0 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value wim; + status = napi_get_named_property( env, argv[ 0 ], "im", &wim ); + assert( status == napi_ok ); + + napi_valuetype wimtype; + status = napi_typeof( env, wim, &wimtype ); + assert( status == napi_ok ); + if ( wimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 1 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value xre; + status = napi_get_named_property( env, argv[ 1 ], "re", &xre ); + assert( status == napi_ok ); + + napi_valuetype xretype; + status = napi_typeof( env, xre, &xretype ); + assert( status == napi_ok ); + if ( xretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 1 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value xim; + status = napi_get_named_property( env, argv[ 1 ], "im", &xim ); + assert( status == napi_ok ); + + napi_valuetype ximtype; + status = napi_typeof( env, xim, &ximtype ); + assert( status == napi_ok ); + if ( ximtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. First argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 2 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value yre; + status = napi_get_named_property( env, argv[ 2 ], "re", &yre ); + assert( status == napi_ok ); + + napi_valuetype yretype; + status = napi_typeof( env, yre, &yretype ); + assert( status == napi_ok ); + if ( yretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 2 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value yim; + status = napi_get_named_property( env, argv[ 2 ], "im", &yim ); + assert( status == napi_ok ); + + napi_valuetype yimtype; + status = napi_typeof( env, yim, &yimtype ); + assert( status == napi_ok ); + if ( yimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 3 ], "re", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have a real component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value zre; + status = napi_get_named_property( env, argv[ 3 ], "re", &zre ); + assert( status == napi_ok ); + + napi_valuetype zretype; + status = napi_typeof( env, zre, &zretype ); + assert( status == napi_ok ); + if ( zretype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have a real component which is a number." ); + assert( status == napi_ok ); + return NULL; + } + + status = napi_has_named_property( env, argv[ 3 ], "im", &hprop ); + assert( status == napi_ok ); + if ( !hprop ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have an imaginary component." ); + assert( status == napi_ok ); + return NULL; + } + + napi_value zim; + status = napi_get_named_property( env, argv[ 3 ], "im", &zim ); + assert( status == napi_ok ); + + napi_valuetype zimtype; + status = napi_typeof( env, zim, &zimtype ); + assert( status == napi_ok ); + if ( zimtype != napi_number ) { + status = napi_throw_type_error( env, NULL, "invalid argument. Third argument must have an imaginary component which a number." ); + assert( status == napi_ok ); + return NULL; + } + + double re0; + status = napi_get_value_double( env, wre, &re0 ); + assert( status == napi_ok ); + + double im0; + status = napi_get_value_double( env, wim, &im0 ); + assert( status == napi_ok ); + + double re1; + status = napi_get_value_double( env, xre, &re1 ); + assert( status == napi_ok ); + + double im1; + status = napi_get_value_double( env, xim, &im1 ); + assert( status == napi_ok ); + + double re2; + status = napi_get_value_double( env, yre, &re2 ); + assert( status == napi_ok ); + + double im2; + status = napi_get_value_double( env, yim, &im2 ); + assert( status == napi_ok ); + + double re3; + status = napi_get_value_double( env, zre, &re3 ); + assert( status == napi_ok ); + + double im3; + status = napi_get_value_double( env, zim, &im3 ); + assert( status == napi_ok ); + + stdlib_complex64_t v = fcn( stdlib_complex64( (float)re0, (float)im0 ), stdlib_complex64( (float)re1, (float)im1 ), stdlib_complex64( (float)re2, (float)im2 ), stdlib_complex64( (float)re3, (float)im3 ) ); + float re; + float im; + stdlib_complex64_reim( v, &re, &im ); + + napi_value obj; + status = napi_create_object( env, &obj ); + assert( status == napi_ok ); + + napi_value vre; + status = napi_create_double( env, (double)re, &vre ); + assert( status == napi_ok ); + + status = napi_set_named_property( env, obj, "re", vre ); + assert( status == napi_ok ); + + napi_value vim; + status = napi_create_double( env, (double)im, &vim ); + assert( status == napi_ok ); + + status = napi_set_named_property( env, obj, "im", vim ); + assert( status == napi_ok ); + + return obj; +}