From 7f19d641647ac4ef313ed88d6b5c140983ce5436 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 15 Jul 2020 08:20:18 +0100 Subject: Squashed 'third_party/immer/' content from commit ad3e3556d git-subtree-dir: third_party/immer git-subtree-split: ad3e3556d38bb75966dd24c61a774970a7c7957e --- extra/guile/src/immer.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 extra/guile/src/immer.cpp (limited to 'extra/guile/src') diff --git a/extra/guile/src/immer.cpp b/extra/guile/src/immer.cpp new file mode 100644 index 000000000000..7933447a8d18 --- /dev/null +++ b/extra/guile/src/immer.cpp @@ -0,0 +1,153 @@ +// +// immer: immutable data structures for C++ +// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente +// +// This software is distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt +// + +#include +#include +#include +#include +#include + +namespace { + +struct guile_heap +{ + static void* allocate(std::size_t size) + { return scm_gc_malloc(size, "immer"); } + + static void* allocate(std::size_t size, immer::norefs_tag) + { return scm_gc_malloc_pointerless(size, "immer"); } + + template + static void deallocate(std::size_t size, void* obj, Tags...) + { scm_gc_free(obj, size, "immer"); } +}; + +using guile_memory = immer::memory_policy< + immer::heap_policy, + immer::no_refcount_policy, + immer::gc_transience_policy, + false>; + +template +using guile_ivector = immer::flex_vector; + +struct dummy +{ + SCM port_ = scm_current_warning_port(); + + dummy(dummy&&) + { scm_puts("~~ dummy move constructor\n", port_); } + + dummy() + { scm_puts("~~ dummy default constructor\n", port_); } + + ~dummy() + { scm_puts("~~ dummy finalized\n", port_); } + + void foo() + { scm_puts("~~ dummy foo\n", port_); } + + int bar(int x) + { + auto res = x + 42; + scm_puts("~~ dummy bar: ", port_); + scm_display(scm::val{res}, port_); + scm_newline(port_); + return res; + } +}; + +template +void func() +{ + auto port = scm_current_warning_port(); + scm_puts("~~ func", port); + scm_display(scm_from_int(I), port); + scm_newline(port); +} + +template +void init_ivector(std::string type_name = "") +{ + using namespace std::string_literals; + + using self_t = guile_ivector; + using size_t = typename self_t::size_type; + + auto name = "ivector"s + (type_name.empty() ? ""s : "-" + type_name); + + scm::type(name) + .constructor([] (scm::args rest) { + return self_t(rest.begin(), rest.end()); + }) + .maker([] (size_t n, scm::args rest) { + return self_t(n, rest ? *rest : scm::val{}); + }) + .define("ref", &self_t::operator[]) + .define("length", &self_t::size) + .define("set", [] (const self_t& v, size_t i, scm::val x) { + return v.set(i, x); + }) + .define("update", [] (const self_t& v, size_t i, scm::val fn) { + return v.update(i, fn); + }) + .define("push", [] (const self_t& v, scm::val x) { + return v.push_back(x); + }) + .define("take", [] (const self_t& v, size_t s) { + return v.take(s); + }) + .define("drop", [] (const self_t& v, size_t s) { + return v.drop(s); + }) + .define("append", [] (self_t v, scm::args rest) { + for (auto x : rest) + v = v + x; + return v; + }) + .define("fold", [] (scm::val fn, scm::val first, const self_t& v) { + return immer::accumulate(v, first, fn); + }) + ; +} + +} // anonymous namespace + +struct bar_tag_t {}; + +extern "C" +void init_immer() +{ + scm::type("dummy") + .constructor() + .finalizer() + .define("foo", &dummy::foo) + .define("bar", &dummy::bar); + + scm::group() + .define("func1", func<1>); + + scm::group() + .define("func2", func<2>) + .define("func3", &dummy::bar); + + scm::group("foo") + .define("func1", func<1>); + + init_ivector(); + init_ivector("u8"); + init_ivector("u16"); + init_ivector("u32"); + init_ivector("u64"); + init_ivector("s8"); + init_ivector("s16"); + init_ivector("s32"); + init_ivector("s64"); + init_ivector("f32"); + init_ivector("f64"); +} -- cgit 1.4.1