Skip to content

Commit 026d198

Browse files
committed
Add native implementation
1 parent 8f1fb02 commit 026d198

File tree

16 files changed

+857
-1
lines changed

16 files changed

+857
-1
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
// MODULES //
4+
5+
var resolve = require( 'path' ).resolve;
6+
var bench = require( '@stdlib/bench' );
7+
var randu = require( '@stdlib/random/base/randu' );
8+
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
9+
var tryRequire = require( '@stdlib/utils/try-require' );
10+
var pkg = require( './../package.json' ).name;
11+
12+
13+
// VARIABLES //
14+
15+
var isnan = tryRequire( resolve( __dirname, './../lib/native.js' ) );
16+
var opts = {
17+
'skip': ( isnan instanceof Error )
18+
};
19+
20+
21+
// MAIN //
22+
23+
bench( pkg, opts, function benchmark( b ) {
24+
var x;
25+
var y;
26+
var i;
27+
28+
b.tic();
29+
for ( i = 0; i < b.iterations; i++ ) {
30+
x = ( randu()*1.0e7 ) - 5.0e6;
31+
y = isnan( x );
32+
if ( !isBoolean( y ) ) {
33+
b.fail( 'should return a boolean' );
34+
}
35+
}
36+
b.toc();
37+
if ( !isBoolean( y ) ) {
38+
b.fail( 'should return a boolean' );
39+
}
40+
b.pass( 'benchmark finished' );
41+
b.end();
42+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
// MODULES //
4+
5+
var bench = require( '@stdlib/bench' );
6+
var hasWebAssemblySupport = require( '@stdlib/utils/detect-wasm-support' );
7+
var randu = require( '@stdlib/random/base/randu' );
8+
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
9+
var pkg = require( './../package.json' ).name;
10+
var isnan = require( './../lib/wasm.js' );
11+
12+
13+
// VARIABLES //
14+
15+
var opts = {
16+
'skip': !hasWebAssemblySupport()
17+
};
18+
19+
20+
// MAIN //
21+
22+
bench( pkg, opts, function benchmark( b ) {
23+
var x;
24+
var y;
25+
var i;
26+
27+
b.tic();
28+
for ( i = 0; i < b.iterations; i++ ) {
29+
x = ( randu()*1.0e7 ) - 5.0e6;
30+
y = isnan( x );
31+
if ( !isBoolean( y ) ) {
32+
b.fail( 'should return a boolean' );
33+
}
34+
}
35+
b.toc();
36+
if ( !isBoolean( y ) ) {
37+
b.fail( 'should return a boolean' );
38+
}
39+
b.pass( 'benchmark finished' );
40+
b.end();
41+
});
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# A `.gyp` file for building a Node.js native add-on.
2+
#
3+
# [1]: https://gyp.gsrc.io/docs/InputFormatReference.md
4+
# [2]: https://gyp.gsrc.io/docs/UserDocumentation.md
5+
{
6+
# List of files to include in this file:
7+
'includes': [
8+
'./include.gypi',
9+
],
10+
11+
# Define variables to be used throughout the configuration for all targets:
12+
'variables': {
13+
# Target name should match the add-on export name:
14+
'addon_target_name%': 'addon',
15+
16+
# Set variables based on the host OS:
17+
'conditions': [
18+
[
19+
'OS=="win"',
20+
{
21+
# Define the object file suffix:
22+
'obj': 'obj',
23+
},
24+
{
25+
# Define the object file suffix:
26+
'obj': 'o',
27+
}
28+
], # end condition (OS=="win")
29+
], # end conditions
30+
}, # end variables
31+
32+
# Define compile targets:
33+
'targets': [
34+
35+
# Target to generate an add-on:
36+
{
37+
# The target name should match the add-on export name:
38+
'target_name': '<(addon_target_name)',
39+
40+
# Define dependencies:
41+
'dependencies': [],
42+
43+
# Define directories which contain relevant include headers:
44+
'include_dirs': [
45+
# NAN absolute file path:
46+
'<!(node -e "require(\'nan\')")',
47+
48+
# Local include directory:
49+
'<@(include_dirs)',
50+
],
51+
52+
# List of source files:
53+
'sources': [
54+
'<@(src_files)',
55+
],
56+
57+
# Settings which should be applied when a target's object files are used as linker input:
58+
'link_settings': {
59+
# Define libraries:
60+
'libraries': [
61+
'<@(libraries)',
62+
],
63+
64+
# Define library directories:
65+
'library_dirs': [
66+
'<@(library_dirs)',
67+
],
68+
},
69+
70+
# C/C++ compiler flags:
71+
'cflags': [
72+
# Enable commonly used warning options:
73+
'-Wall',
74+
75+
# Aggressive optimization:
76+
'-O3',
77+
],
78+
79+
# C specific compiler flags:
80+
'cflags_c': [
81+
# Specify the C standard to which a program is expected to conform:
82+
'-std=c99',
83+
],
84+
85+
# C++ specific compiler flags:
86+
'cflags_cpp': [
87+
# Specify the C++ standard to which a program is expected to conform:
88+
'-std=c++11',
89+
],
90+
91+
# Linker flags:
92+
'ldflags': [],
93+
94+
# Apply conditions based on the host OS:
95+
'conditions': [
96+
[
97+
'OS=="mac"',
98+
{
99+
# Linker flags:
100+
'ldflags': [
101+
'-undefined dynamic_lookup',
102+
'-Wl,-no-pie',
103+
'-Wl,-search_paths_first',
104+
],
105+
},
106+
], # end condition (OS=="mac")
107+
[
108+
'OS!="win"',
109+
{
110+
# C/C++ flags:
111+
'cflags': [
112+
# Generate platform-independent code:
113+
'-fPIC',
114+
],
115+
},
116+
], # end condition (OS!="win")
117+
], # end conditions
118+
}, # end target <(addon_target_name)
119+
120+
# Target to copy a generated add-on to a standard location:
121+
{
122+
'target_name': 'copy_addon',
123+
124+
# Declare that the output of this target is not linked:
125+
'type': 'none',
126+
127+
# Define dependencies:
128+
'dependencies': [
129+
# Require that the add-on be generated before building this target:
130+
'<(addon_target_name)',
131+
],
132+
133+
# Define a list of actions:
134+
'actions': [
135+
{
136+
'action_name': 'copy_addon',
137+
'message': 'Copying addon...',
138+
139+
# Explicitly list the inputs in the command-line invocation below:
140+
'inputs': [],
141+
142+
# Declare the expected outputs:
143+
'outputs': [
144+
'<(addon_output_dir)/<(addon_target_name).node',
145+
],
146+
147+
# Define the command-line invocation:
148+
'action': [
149+
'cp',
150+
'<(PRODUCT_DIR)/<(addon_target_name).node',
151+
'<(addon_output_dir)/<(addon_target_name).node',
152+
],
153+
},
154+
], # end actions
155+
}, # end target copy_addon
156+
], # end targets
157+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# A GYP include file for building a Node.js native add-on.
2+
#
3+
# Main documentation:
4+
# [1]: https://gyp.gsrc.io/docs/InputFormatReference.md
5+
# [2]: https://gyp.gsrc.io/docs/UserDocumentation.md
6+
{
7+
# Define variables to be used throughout the configuration for all targets:
8+
'variables': {
9+
# Source directory:
10+
'src_dir': './src',
11+
12+
# Include directories:
13+
'include_dirs': [
14+
'<!@(node -e "var arr = require(\'@stdlib/tools/library-manifest\')(\'./manifest.json\',{},{\'basedir\':process.cwd(),\'paths\':\'posix\'}).include; for ( var i = 0; i < arr.length; i++ ) { console.log( arr[ i ] ); }")',
15+
],
16+
17+
# Add-on destination directory:
18+
'addon_output_dir': './src',
19+
20+
# Source files:
21+
'src_files': [
22+
'<(src_dir)/addon.cpp',
23+
'<!@(node -e "var arr = require(\'@stdlib/tools/library-manifest\')(\'./manifest.json\',{},{\'basedir\':process.cwd(),\'paths\':\'posix\'}).src; for ( var i = 0; i < arr.length; i++ ) { console.log( arr[ i ] ); }")',
24+
],
25+
26+
# Library dependencies:
27+
'libraries': [
28+
'<!@(node -e "var arr = require(\'@stdlib/tools/library-manifest\')(\'./manifest.json\',{},{\'basedir\':process.cwd(),\'paths\':\'posix\'}).libraries; for ( var i = 0; i < arr.length; i++ ) { console.log( arr[ i ] ); }")',
29+
],
30+
31+
# Library directories:
32+
'library_dirs': [
33+
'<!@(node -e "var arr = require(\'@stdlib/tools/library-manifest\')(\'./manifest.json\',{},{\'basedir\':process.cwd(),\'paths\':\'posix\'}).libpath; for ( var i = 0; i < arr.length; i++ ) { console.log( arr[ i ] ); }")',
34+
],
35+
}, # end variables
36+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Header file containing function declarations for computing the hypotenuse while avoiding overflow and underflow.
3+
*/
4+
#ifndef STDLIB_ISNAN_H
5+
#define STDLIB_ISNAN_H
6+
7+
/*
8+
* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler.
9+
*/
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
/**
15+
* Tests if a numeric value is `NaN`.
16+
*/
17+
bool stdlib_isnan( const double x );
18+
19+
#ifdef __cplusplus
20+
}
21+
#endif
22+
23+
#endif // !STDLIB_ISNAN_H

lib/node_modules/@stdlib/math/base/assert/is-nan/lib/is_nan.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* // returns false
1818
*/
1919
function isnan( x ) {
20-
return (x !== x);
20+
return ( x !== x );
2121
} // end FUNCTION isnan()
2222

2323

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
// MODULES //
4+
5+
var addon = require( './../src/addon.node' );
6+
7+
8+
// MAIN //
9+
10+
/**
11+
* Tests if a numeric value is `NaN`.
12+
*
13+
* @name isnan
14+
* @type {Function}
15+
* @param {number} x - value to test
16+
* @returns {boolean} boolean indicating whether the value is `NaN`
17+
*
18+
* @example
19+
* var bool = isnan( NaN );
20+
* // returns true
21+
*
22+
* @example
23+
* var bool = isnan( 7.0 );
24+
* // returns false
25+
*/
26+
var isnan = addon.isnan;
27+
28+
29+
// EXPORTS //
30+
31+
module.exports = isnan;

0 commit comments

Comments
 (0)