diff --git a/CMakeLists.txt b/CMakeLists.txt index e6291a41c..422c1e8b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,11 +19,18 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_VERBOSE_MAKEFILE OFF) +string(CONCAT UNSTABLE_OPTIMIZATION_OPTIONS # JOIN available if VERSION > 3.12 + # "-flto " # This optimization causes a SEGV when compiling with Clang 10. + # "-fmerge-all-constants " # This optimization is very effective in reducing binary size, but non-standard to the C++ standard. + # "-march=native " # This optimization causes "Illegal instruction" error (is Valgrind's bug) on CI. + # "-mtune=native " + ) + set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic -pipe") set(CMAKE_CXX_FLAGS_DEBUG "-Og -g") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG") -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") # NOTE: -march=native causes "Illegal instruction" error (is Valgrind's bug) on CI. +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG ${UNSTABLE_OPTIMIZATION_OPTIONS}") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) @@ -171,6 +178,7 @@ check(internal-definition) check(let-syntax) check(letrec-syntax) check(numerical-operations) +check(parameterize) check(r4rs) check(r4rs-appendix) check(r5rs) @@ -178,6 +186,7 @@ check(r7rs) check(sicp-1) check(srfi-8) check(transformer) +check(with-exception-handler) file(GLOB ${PROJECT_NAME}_TEST_CXX ${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp) foreach(FILEPATH IN LISTS ${PROJECT_NAME}_TEST_CXX) diff --git a/README.md b/README.md index 72b3eb067..7850e3a33 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.232.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.278.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.232_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.278_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.232 +Meevax Lisp System, version 0.4.278 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 2a4561f41..95970ea07 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.232 +0.4.278 diff --git a/basis/r4rs-essential.ss b/basis/r4rs-essential.ss index 815241138..6b8e29524 100644 --- a/basis/r4rs-essential.ss +++ b/basis/r4rs-essential.ss @@ -2,7 +2,9 @@ (import (meevax character) (meevax control) (meevax environment) - (meevax equivalence) + (rename (meevax comparator) + (identity=? eq?) + (normally=? eqv?)) (meevax foreign-function) (meevax list) (meevax number) @@ -11,8 +13,7 @@ (meevax read) (meevax string) (meevax symbol) - (rename (meevax syntax) - (call-with-current-continuation! call-with-current-continuation)) + (meevax syntax) (meevax vector) (meevax write) (srfi 211 explicit-renaming)) @@ -541,6 +542,9 @@ (begin (apply map f x xs) (if #f #f)))) + (define (call-with-current-continuation f) + (call-with-current-continuation! f)) + (define (call-with-input-file path f) ; r7rs incompatible (values unsupported) (define (call-with-input-port port f) (let ((result (f port))) diff --git a/basis/r5rs.ss b/basis/r5rs.ss index 0a61ff1ff..ce59ce93b 100644 --- a/basis/r5rs.ss +++ b/basis/r5rs.ss @@ -1,39 +1,48 @@ (define-library (scheme r5rs continuation) (import (meevax context) - (only (meevax syntax) define-syntax) - (rename (scheme r4rs) (call-with-current-continuation r4rs:call/cc))) + (only (meevax dynamic-environment) load-auxiliary store-auxiliary) + (only (meevax syntax) define-syntax call-with-current-continuation!) + (except (scheme r4rs) call-with-current-continuation)) (export call-with-current-continuation dynamic-wind exit) - (begin (define %current-dynamic-extents '()) ; https://www.cs.hmc.edu/~fleck/envision/scheme48/meeting/node7.html + ; https://www.cs.hmc.edu/~fleck/envision/scheme48/meeting/node7.html + + (begin (define (current-dynamic-extents) + (load-auxiliary 0)) + + (define (install-dynamic-extents! extents) + (store-auxiliary 0 extents)) (define (dynamic-wind before thunk after) (before) - (set! %current-dynamic-extents (cons (cons before after) %current-dynamic-extents)) + (install-dynamic-extents! (cons (cons before after) + (current-dynamic-extents))) ((lambda (result) ; TODO let-values - (set! %current-dynamic-extents (cdr %current-dynamic-extents)) + (install-dynamic-extents! (cdr (current-dynamic-extents))) (after) result) ; TODO (apply values result) (thunk))) (define (call-with-current-continuation procedure) (define (windup! from to) - (set! %current-dynamic-extents from) + (install-dynamic-extents! from) (cond ((eq? from to)) ((null? from) (windup! from (cdr to)) ((caar to))) ((null? to) ((cdar from)) (windup! (cdr from) to)) (else ((cdar from)) (windup! (cdr from) (cdr to)) ((caar to)))) - (set! %current-dynamic-extents to)) - (let ((current-dynamic-extents %current-dynamic-extents)) - (r4rs:call/cc (lambda (k1) - (procedure (lambda (k2) - (windup! %current-dynamic-extents current-dynamic-extents) - (k1 k2))))))) + (install-dynamic-extents! to)) + (let ((dynamic-extents (current-dynamic-extents))) + (call-with-current-continuation! + (lambda (continue) + (procedure (lambda (x) + (windup! (current-dynamic-extents) dynamic-extents) + (continue x))))))) (define (exit . normally?) (for-each (lambda (before/after) ((cdr before/after))) - %current-dynamic-extents) + (current-dynamic-extents)) (apply emergency-exit normally?)))) (define-library (scheme r5rs) diff --git a/basis/r7rs.ss b/basis/r7rs.ss index 0be4d47f6..20565fa4e 100644 --- a/basis/r7rs.ss +++ b/basis/r7rs.ss @@ -2,21 +2,11 @@ (import (only (meevax error) error? read-error? file-error?) (only (meevax number) exact-integer?) (only (meevax vector) vector-append vector-copy vector-copy! string->vector) - (only (meevax port) binary-port? - textual-port? - port? - input-port-open? - output-port-open? - standard-input-port - standard-output-port - standard-error-port - eof-object - get-ready? - get-char - get-char! - put-char - put-string - %flush-output-port) + (only (meevax port) + binary-port? textual-port? port? input-port-open? output-port-open? + standard-input-port standard-output-port standard-error-port + eof-object get-ready? get-char get-char! put-char put-string + %flush-output-port) (only (meevax string) string-copy! vector->string) (only (meevax version) features) (scheme r5rs) @@ -61,7 +51,7 @@ syntax-rules _ ... - ; syntax-error + syntax-error define ; define-values define-syntax @@ -286,6 +276,11 @@ (cadr form)) ,@(cddr form))))) + (define-syntax syntax-error + (er-macro-transformer + (lambda (form rename compare) + (apply error (cdr form))))) + (define (floor-quotient x y) (floor (/ x y))) diff --git a/basis/srfi-211.ss b/basis/srfi-211.ss index 0e00fe979..15e81708b 100644 --- a/basis/srfi-211.ss +++ b/basis/srfi-211.ss @@ -13,7 +13,9 @@ (export sc-macro-transformer rsc-macro-transformer make-syntactic-closure identifier?)) (define-library (srfi 211 explicit-renaming) - (import (meevax equivalence) + (import (rename (meevax comparator) + (identity=? eq?) + (normally=? eqv?)) (meevax list) (meevax macro) (meevax pair) diff --git a/basis/srfi-34.ss b/basis/srfi-34.ss index 9e0ffe6de..99735fce9 100644 --- a/basis/srfi-34.ss +++ b/basis/srfi-34.ss @@ -19,37 +19,48 @@ ; IN THE SOFTWARE. (define-library (srfi 34) - (import (only (meevax error) throw) + (import (only (meevax dynamic-environment) load-auxiliary store-auxiliary) + (only (meevax error) throw) (scheme r5rs)) (export with-exception-handler raise raise-continuable guard) - (begin (define %current-exception-handlers (list throw)) + (begin (define (current-exception-handlers) + (load-auxiliary 2)) - (define (%with-exception-handlers new-handlers thunk) - (let ((old-handlers %current-exception-handlers)) + (define (install-exception-handlers! handlers) + (store-auxiliary 2 handlers)) + + (define (with-exception-handlers new-handlers thunk) + (let ((old-handlers (current-exception-handlers))) (dynamic-wind - (lambda () (set! %current-exception-handlers new-handlers)) ; install + (lambda () (install-exception-handlers! new-handlers)) ; install thunk - (lambda () (set! %current-exception-handlers old-handlers))))) ; uninstall + (lambda () (install-exception-handlers! old-handlers))))) ; uninstall (define (with-exception-handler handler thunk) - (%with-exception-handlers (cons handler %current-exception-handlers) thunk)) + (with-exception-handlers (cons handler (current-exception-handlers)) thunk)) (define (raise x) - (let ((inner (car %current-exception-handlers)) - (outer (cdr %current-exception-handlers))) - (%with-exception-handlers outer + (let ((inner (car (current-exception-handlers))) + (outer (cdr (current-exception-handlers)))) + (with-exception-handlers outer (lambda () - (inner x) - (error "If the handler returns, a secondary exception is raised in the same dynamic environment as the handler"))))) + (if (procedure? inner) + (inner x) + (throw x)) + (throw x))))) (define (raise-continuable x) - (let ((inner (car %current-exception-handlers)) - (outer (cdr %current-exception-handlers))) - (%with-exception-handlers outer - (lambda () - (inner x))))) + (let ((inner (car (current-exception-handlers))) + (outer (cdr (current-exception-handlers)))) + (with-exception-handlers outer + (lambda () + (if (procedure? inner) + (inner x) + (throw x)))))) + + (declare-raiser raise) (define-syntax guard (syntax-rules () @@ -107,7 +118,4 @@ clause1 clause2 ...) (if test (begin result1 result2 ...) - (guard-aux reraise clause1 clause2 ...))))) - - ) - ) + (guard-aux reraise clause1 clause2 ...))))))) diff --git a/basis/srfi-39.ss b/basis/srfi-39.ss index a045aa1dc..ae9b8d604 100644 --- a/basis/srfi-39.ss +++ b/basis/srfi-39.ss @@ -19,61 +19,48 @@ ; SOFTWARE. (define-library (srfi 39) - (import (scheme r5rs) + (import (only (meevax dynamic-environment) load-auxiliary store-auxiliary) + (scheme r5rs) (srfi 211 explicit-renaming)) (export make-parameter parameterize) - (begin (define make-parameter - (lambda (init . conv) - (let ((converter (if (null? conv) - (lambda (x) x) - (car conv)))) - (let ((global-cell - (cons #f (converter init)))) - (letrec ((parameter - (lambda new-val - (let ((cell (dynamic-lookup parameter global-cell))) - (cond ((null? new-val) - (cdr cell)) - ((null? (cdr new-val)) - (set-cdr! cell (converter (car new-val)))) - (else ; this case is needed for parameterize - (converter (car new-val)))))))) - (set-car! global-cell parameter) - parameter))))) + (begin (define (current-dynamic-bindings) + (load-auxiliary 1)) - (define dynamic-bind - (lambda (parameters values body) - (let* ((old-local - (dynamic-env-local-get)) - (new-cells - (map (lambda (parameter value) - (cons parameter (parameter value #f))) - parameters - values)) - (new-local - (append new-cells old-local))) - (dynamic-wind - (lambda () (dynamic-env-local-set! new-local)) - body - (lambda () (dynamic-env-local-set! old-local)))))) + (define (install-dynamic-bindings! bindings) + (store-auxiliary 1 bindings)) - (define dynamic-lookup - (lambda (parameter global-cell) - (or (assq parameter (dynamic-env-local-get)) - global-cell))) + (define (make-parameter init . converter) + (let* ((convert (if (null? converter) + (lambda (x) x) + (car converter))) + (default (cons #f (convert init)))) + (letrec ((parameter + (lambda value + (let ((cell (or (assq parameter (current-dynamic-bindings)) default))) + (cond ((null? value) + (cdr cell)) + ((null? (cdr value)) + (set-cdr! cell (convert (car value)))) + (else ; Apply converter to value + (convert (car value)))))))) + (set-car! default parameter) + parameter))) - (define dynamic-env-local '()) - - (define (dynamic-env-local-get) dynamic-env-local) - - (define (dynamic-env-local-set! new-env) - (set! dynamic-env-local new-env)) + (define (dynamic-bind parameters values body) + (let* ((outer (current-dynamic-bindings)) + (inner (map (lambda (parameter value) + (cons parameter (parameter value 'apply-converter-to-value))) + parameters + values))) + (dynamic-wind (lambda () (install-dynamic-bindings! (append inner outer))) + body + (lambda () (install-dynamic-bindings! outer))))) (define-syntax parameterize (er-macro-transformer (lambda (form rename compare) - `(,(rename 'dynamic-bind) (,(rename 'list) ,@(map car (cadr form))) + `(,(rename 'dynamic-bind) (,(rename 'list) ,@(map car (cadr form))) (,(rename 'list) ,@(map cadr (cadr form))) (,(rename 'lambda) () ,@(cddr form)))))))) diff --git a/include/meevax/kernel/character.hpp b/include/meevax/kernel/character.hpp index 3965a4511..6ea002f59 100644 --- a/include/meevax/kernel/character.hpp +++ b/include/meevax/kernel/character.hpp @@ -17,8 +17,6 @@ #ifndef INCLUDED_MEEVAX_KERNEL_CHARACTER_HPP #define INCLUDED_MEEVAX_KERNEL_CHARACTER_HPP -#include - #include namespace meevax diff --git a/include/meevax/kernel/equivalence.hpp b/include/meevax/kernel/comparator.hpp similarity index 83% rename from include/meevax/kernel/equivalence.hpp rename to include/meevax/kernel/comparator.hpp index 3af9ea328..00a38ce12 100644 --- a/include/meevax/kernel/equivalence.hpp +++ b/include/meevax/kernel/comparator.hpp @@ -14,10 +14,10 @@ limitations under the License. */ -#ifndef INCLUDED_MEEVAX_KERNEL_EQUIVALENCE_HPP -#define INCLUDED_MEEVAX_KERNEL_EQUIVALENCE_HPP +#ifndef INCLUDED_MEEVAX_KERNEL_COMPARATOR_HPP +#define INCLUDED_MEEVAX_KERNEL_COMPARATOR_HPP -#include +#include namespace meevax { @@ -37,4 +37,4 @@ inline namespace kernel } // namespace kernel } // namespace meevax -#endif // INCLUDED_MEEVAX_KERNEL_EQUIVALENCE_HPP +#endif // INCLUDED_MEEVAX_KERNEL_COMPARATOR_HPP diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 6c6698342..5c5f4d322 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -18,9 +18,7 @@ #define INCLUDED_MEEVAX_KERNEL_COMPLEX_HPP #include -#include -#include #include namespace meevax diff --git a/include/meevax/kernel/configurator.hpp b/include/meevax/kernel/configurator.hpp index 55aa7120f..de194d368 100644 --- a/include/meevax/kernel/configurator.hpp +++ b/include/meevax/kernel/configurator.hpp @@ -19,11 +19,8 @@ #include -#include #include -#include #include -#include #include #include @@ -39,12 +36,12 @@ inline namespace kernel explicit configurator() {} - IMPORT(environment, evaluate, NIL); - IMPORT(environment, load, NIL); - IMPORT(environment, read, NIL); + IMPORT(environment, evaluate, ); + IMPORT(environment, load, ); + IMPORT(environment, read, ); template - using dispatcher = std::unordered_map; + using dispatcher = std::unordered_map>; public: static inline auto batch = false; @@ -80,49 +77,52 @@ inline namespace kernel { std::make_pair('b', [](auto&&...) { - return make(batch = true); + batch = true; }), std::make_pair('d', [](auto&&...) { - return make(debug = true); + debug = true; }), - std::make_pair('h', [](auto&&...) -> value_type + std::make_pair('h', [](auto&&...) { configurator::display_help(); - throw exit_status::success; + throw success; }), std::make_pair('i', [](auto&&...) { - return make(interactive = true); + interactive = true; }), - std::make_pair('v', [](auto&&...) -> value_type + std::make_pair('t', [](auto&&...) + { + trace = true; + }), + + std::make_pair('v', [](auto&&...) { configurator::display_version(); - throw exit_status::success; + throw success; }), }; static inline const dispatcher short_options_with_arguments { - std::make_pair('e', [](const_reference x, auto&&...) + std::make_pair('e', [](auto&& x) { print(interaction_environment().as().evaluate(x)); - return unspecified; }), - std::make_pair('l', [](const_reference x, auto&&...) + std::make_pair('l', [](auto&& x) { - return interaction_environment().as().load(x.as_const()); + interaction_environment().as().load(x.template as_const()); }), - std::make_pair('w', [](const_reference x, auto&&...) + std::make_pair('w', [](auto&& x) { print(x); - return unspecified; }), }; @@ -130,54 +130,52 @@ inline namespace kernel { std::make_pair("batch", [](auto&&...) { - return make(batch = true); + batch = true; }), std::make_pair("debug", [](auto&&...) { - return make(debug = true); + debug = true; }), - std::make_pair("help", [](auto&&...) -> value_type + std::make_pair("help", [](auto&&...) { display_help(); - throw exit_status::success; + throw success; }), std::make_pair("interactive", [](auto&&...) { - return make(interactive = true); + interactive = true; }), std::make_pair("trace", [](auto&&...) { - return make(trace = true); + trace = true; }), - std::make_pair("version", [](auto&&...) -> value_type + std::make_pair("version", [](auto&&...) { display_version(); - throw exit_status::success; + throw success; }), }; static inline const dispatcher long_options_with_arguments { - std::make_pair("evaluate", [](const_reference x, auto&&...) + std::make_pair("evaluate", [](auto&& x) { print(interaction_environment().as().evaluate(x)); - return unspecified; }), - std::make_pair("load", [](const_reference x, auto&&...) + std::make_pair("load", [](auto&& x) { - return interaction_environment().as().load(x.as_const()); + interaction_environment().as().load(x.template as_const()); }), - std::make_pair("write", [](const_reference x, auto&&...) + std::make_pair("write", [](auto&& x) { print(x); - return unspecified; }), }; @@ -219,7 +217,7 @@ inline namespace kernel } else { - throw error(make(concatenate("option -", name, " requires an argument"))); + throw std::runtime_error(concatenate("option -", name, " requires an argument")); } } else if (auto iter = short_options.find(*current_short_option); iter != std::end(short_options)) @@ -228,8 +226,7 @@ inline namespace kernel } else { - throw error(make("unknown short-option"), - make(*current_short_option)); + throw std::runtime_error(concatenate("unknown short-option ", *current_short_option)); } } } @@ -247,7 +244,7 @@ inline namespace kernel } else { - throw error(make(concatenate("option --", current_long_option, " requires an argument"))); + throw std::runtime_error(concatenate("option --", current_long_option, " requires an argument")); } } else if (auto iter = long_options.find(current_long_option); iter != std::end(long_options)) @@ -256,17 +253,14 @@ inline namespace kernel } else { - throw error(make("unknown long-option"), - make(*current_option)); + throw std::runtime_error(concatenate("unknown long-option ", *current_option)); } } else { interactive = false; - return load(*current_option); + load(*current_option); } - - return unspecified; }(); } }; diff --git a/include/meevax/kernel/environment.hpp b/include/meevax/kernel/environment.hpp index 3bd1e1c97..1ddab7f1a 100644 --- a/include/meevax/kernel/environment.hpp +++ b/include/meevax/kernel/environment.hpp @@ -21,7 +21,6 @@ #include #include #include -#include namespace meevax { diff --git a/include/meevax/kernel/error.hpp b/include/meevax/kernel/error.hpp index 7b5e35b4b..8a97ef8da 100644 --- a/include/meevax/kernel/error.hpp +++ b/include/meevax/kernel/error.hpp @@ -17,57 +17,51 @@ #ifndef INCLUDED_MEEVAX_KERNEL_ERROR_HPP #define INCLUDED_MEEVAX_KERNEL_ERROR_HPP -#include - -#include -#include -#include - -/* ---- Error ------------------------------------------------------------------ - * - * - error - * |-- file-error - * |-- read_error - * `-- syntax_error - * - * -------------------------------------------------------------------------- */ +#include namespace meevax { inline namespace kernel { - enum class exit_status : int - { - success = EXIT_SUCCESS, - failure = EXIT_FAILURE, - }; + constexpr auto success = EXIT_SUCCESS; + constexpr auto failure = EXIT_FAILURE; struct error : public virtual pair { using pair::pair; + explicit error(std::string const&, const_reference = unit); + auto irritants() const noexcept -> const_reference; auto message() const noexcept -> const_reference; + [[noreturn]] // NOTE: GCC ignores this attribute when accessed through pointer (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84476) virtual auto raise() const -> void; - virtual auto what() const -> std::string; + auto what() const -> std::string; }; auto operator <<(std::ostream &, error const&) -> std::ostream &; + /* + - error + |-- file-error + `-- read_error + */ #define DEFINE_ERROR(TYPENAME) \ struct TYPENAME ## _error : public error \ { \ using error::error; \ \ - ~TYPENAME ## _error() override = default; \ + auto raise() const -> void override \ + { \ + throw *this; \ + } \ } DEFINE_ERROR(file); DEFINE_ERROR(read); - DEFINE_ERROR(syntax); template auto with_exception_handler(Thunk && thunk) @@ -76,35 +70,20 @@ inline namespace kernel { return thunk(); } - - catch (exit_status const value) // NOTE: emergency-exit + catch (int const status) // NOTE: emergency-exit { - gc.clear(); // NOTE: - return underlying_cast(value); + gc.clear(); + return status; } - - catch (const_reference error) // NOTE: procedure `throw` (Terminate the program without running any outstanding dynamic-wind after procedures) - { - std::cerr << "; " << error << std::endl; - return underlying_cast(exit_status::failure); - } - catch (error const& error) // NOTE: system-error { std::cerr << "; " << error << std::endl; - return underlying_cast(exit_status::failure); + return failure; } - catch (std::exception const& error) { - std::cerr << "; error " << std::quoted(error.what()) << std::endl; - return underlying_cast(exit_status::failure); - } - - catch (...) - { - std::cerr << "; error: An unknown object was thrown that was neither a Meevax exception type nor a C++ standard exception type." << std::endl; - return underlying_cast(exit_status::failure); + std::cerr << "; " << error.what() << std::endl; + return failure; } } } // namespace kernel diff --git a/include/meevax/kernel/heterogeneous.hpp b/include/meevax/kernel/heterogeneous.hpp index 8f297bb82..9098dd349 100644 --- a/include/meevax/kernel/heterogeneous.hpp +++ b/include/meevax/kernel/heterogeneous.hpp @@ -17,18 +17,26 @@ #ifndef INCLUDED_MEEVAX_KERNEL_POINTER_HPP #define INCLUDED_MEEVAX_KERNEL_POINTER_HPP +#include #include +#include #include -#include +#include +#include #include +#include +#include #include #include +#include #include namespace meevax { inline namespace kernel { + using null = std::nullptr_t; + template