Fast, orthogonal, open multi-methods. Supersedes yomm11.

YOMM2

This is a complete rewrite of YOMM11, which is now deprecated. This library is much better, see here to find out why.

TL;DR

If you are familiar with the concept of open multi-methods, or prefer to learn by reading code, go directly to the synopsis

Open Methods in a Nutshell

Cross-cutting Concerns and the Expression Problem

You have a matrix math library. It deals with all sort of matrices: dense, diagonal, tri-diagonal, etc. Each matrix subtype has a corresponding class in a hierarchy rooted in Matrix.

Now you would like to render Matrix objects as JSON strings. The representation will vary depending on the exact type of the object; for example, if a matrix is a DiagonalMatrix, you only need to store the diagonal - the other elements are all zeroes.

This is an example of a "cross-cutting concern". How do you do it?

It turns out that OOP doesn't offer a good solution to this.

You can stick a pure virtual to_json function in the Matrix base class and override it in the subclasses. It is an easy solution but it has severe drawbacks. It requires you to change the Matrix class and its subclasses, and recompile the library. And now all the applications that use it will contain the to_json functions even if they don't need them, because of the way virtual functions are implemented.

Or you may resort on a "type switch": have the application test for each category and generate the JSON accordingly. This is tedious, error prone and, above all, not extensible. Adding a new matrix subclass requires updating all the type switches. The Visitor pattern also suffers from this flaw.

Wouldn't it be nice if you could add behavior to existing types, just as easily and unintrusively as you can extend existing class hierarchies via derivation? What if you could solve the so-called Expression Problem:

behaviors += types
types += behaviors

This is exactly what Open Methods are all about: solving the Expression Problem.

Let's look at an example.

// -----------------------------------------------------------------------------
// library code

struct matrix {
    virtual ~matrix() {}
    // ...
};

struct dense_matrix    : matrix { /* ... */ };
struct diagonal_matrix : matrix { /* ... */ };

// -----------------------------------------------------------------------------
// application code

#include <yorel/yomm2/cute.hpp>

using yorel::yomm2::virtual_;

register_class(matrix);
register_class(dense_matrix, matrix);
register_class(diagonal_matrix, matrix);

declare_method(string, to_json, (virtual_<const matrix&>));

define_method(string, to_json, (const dense_matrix& m)) {
    return "json for dense matrix...";
}

define_method(string, to_json, (const diagonal_matrix& m)) {
    return "json for diagonal matrix...";
}

int main() {
    yorel::yomm2::update_methods();

    shared_ptr<const matrix> a = make_shared<dense_matrix>();
    shared_ptr<const matrix> b = make_shared<diagonal_matrix>();

    cout << to_json(*a) << "\n"; // json for dense matrix
    cout << to_json(*b) << "\n"; // json for diagonal matrix

    return 0;
}

The declare_method line declares an open method called to_jsonthat takes one virtual argument of type const matrix& and returns a string. The virtual_<> decorator specifies that the argument must be taken into account to select the appropriate specialization. In essence, this is the same thing as having a virtual string to_json() const inside class Matrix - except that the virtual function lives outside of any classes, and you can add as many as you want without modifying the classes.

NOTE: DO NOT specify argument names, i.e. virtual_<const matrix&> arg is not permitted.

The following two define_method ... end_method blocks define two implementations for the to_json method: one for dense matrices, and one for diagonal matrices.

yorel::yomm2::update_methods() must be called before any method is called, and after dynamically loading and unloading shared libraries.

Multiple Dispatch

Methods can have more than one virtual argument. This is handy in certain situations, for example to implement binary operations on matrices:

// -----------------------------------------------------------------------------
// matrix * matrix

declare_method(
    shared_ptr<const matrix>,
    times,
    (virtual_<shared_ptr<const matrix>>, virtual_<shared_ptr<const matrix>>));

// catch-all matrix * matrix -> dense_matrix
define_method(
    shared_ptr<const matrix>,
    times,
    (shared_ptr<const matrix> a, shared_ptr<const matrix> b)) {
    return make_shared<dense_matrix>();
}

// diagonal_matrix * diagonal_matrix -> diagonal_matrix
define_method(
    shared_ptr<const matrix>,
    times,
    (shared_ptr<const diagonal_matrix> a, shared_ptr<const diagonal_matrix> b)) {
    return make_shared<diagonal_matrix>();
}

Performance

Don't worry about it. Open methods are almost as fast as ordinary virtual member functions once you turn on optimization (-O2). With both clang and gcc, dispatching a call to a method with one virtual argument is only 15-30% slower than calling the equivalent virtual member function. If the body of the method does any amount of work, the difference is unnoticeable. See the implementation notes for benchmarks and assembly listings.

Building and Installing

Make sure that you have the following dependencies:

  • a C++17 capable compiler

  • cmake version 3.5 or above

Clone the repository:

git clone https://github.com/jll63/yomm2.git
cd yomm2

Create a build directory and run cmake then make:

mkdir build
cd build
cmake ..
make

If you want to run the tests:

cmake .. -DYOMM2_ENABLE_TESTS=1
make && ctest

YOMM2 uses several Boost libraries:

  1. Preprocessor, DynamicBitset, TypeTraits: included by YOMM2 headers

  2. Boost.Test: only used to run the test suite

If these libraries are already available on your machine, and they can by cmake, they will be used. In this case, make sure that the pre-installed libraries are at version 1.65 or above. If Boost is not found, the latest version will be downloaded, and the Boost headers mentioned in section (1) will be installed along YOMM2 (if you decide to make install).

If you also want to run the benchmarks (and in this case you really want a release build):

cmake .. -DYOMM2_ENABLE_TESTS=1 -DYOMM2_ENABLE_BENCHMARKS=1 -DCMAKE_BUILD_TYPE=Release
make && tests/benchmarks # wow it's fast!

This will automatically download the dependency benchmark, build it and finally install it to ./extern within the root directory of yomm2.

Finally, if you like it and you want to install it:

# either:
sudo make install
# or:
make install DESTDIR=/path/to/my/libs

This will install the library and headers, as well as a CMake package configuration.

Make sure to add the install location to CMAKE_PREFIX_PATH so that you can use find_package(YOMM2) from your including project. For linking, the use target_link_library(<your_target> YOMM2::yomm2). This will automatically add the necessary include directories, so this should be all you need to do to link to yomm2.

Going Further

The Reference is here.

The library comes with a series of examples:

I presented the library at CppCon 2018. Here are the video recording and the slides.

Owner
Comments
  • Friendship with multi-methods

    Friendship with multi-methods

    I have been a user of yomm11 for quite some time. At the time where I started using it I faced a problem with the use of multi-methods from classes, which I solved by using a suggestion by @jll63.

    The example elaborated at the time is attached for reference: much like in the matrix example, multi-methods are used to handle a hierarchy of classes, however in this case the "entrypoint" is a public method of the Painter class.

    The requirement was to access some private member of the Painter class from the multi-methods. Since it is not possible to declare a multi-method as a member of the class, the solution was to friend the class generated by the preprocessor, and pass the instance to the various multi-methods.

    However, in yomm2 the same solution seems more difficult to achieve: the library generates a numeric ID for the namespace where it declares the methods, which I presume depends on the order of declaration and thus cannot be reliably predicted. Attached is my attempt to solve this, but I have the feeling that it is a brittle solution.

    Any suggestions for the above? Would a variant of declare_method and define_method, to use within a class eligible for implementation? For example:

    class Painter
    {
    public:
        void paint(const Geometry& geometry);
    private:
        int counter = 0;
        declare_class_method(void, paintObject, (virtual_<const Geometry&>));
    };
    
    define_class_method(void, Painter, paintObject, (const Geometry& /*geometry*/)) {
        // ...
    }
    
  • specializing on `shared_ptr<Animal> const&`  doesn't work for me.

    specializing on `shared_ptr const&` doesn't work for me.

    Thanks for this library. It feels like I have a new superpower!

    According to the reference doc, it should be possible to dispatch on shared_ptr<Animal> const& but if I add the const ref qualifier, I get lots of template error messages, the first of which says Static_assert failed due to requirement 'shared_ptr_traits<const std::__1::shared_ptr<ScalarT<double> > &>::is_shared_ptr'. I assume I am doing something wrong.

    Here is an example. It works as is. But if I change the #if 1 to #if 0 to enable const ref for all arguments, then it doesn't compile.

    I am compiling with Clang in Xcode 12.3.

    #include <yorel/yomm2/cute.hpp>
    #include <iostream>
    #include <memory>
    #include <string>
    
    #if 1
    #define CONSTREF
    #else
    #define CONSTREF const&
    #endif
    
    using yorel::yomm2::virtual_;
    
    class Value { // base class for values
    public:
    	virtual ~Value() = default;
    };
    
    class Scalar : public Value {};  // base class for scalars
    
    template <class T>
    class ScalarT : public Scalar {
    	T x_;
    public:
    	ScalarT(T x) : x_(x) {}
    	T x() const noexcept { return x_; }
    };
    
    // convenience function to create a shared ScalarT.
    template <class T>
    std::shared_ptr<Value> num(T x) { return std::make_shared<ScalarT<T>>(x); }
    
    register_class(Value);
    register_class(Scalar, Value);
    register_class(ScalarT<int>, Scalar);
    register_class(ScalarT<double>, Scalar);
    
    declare_method(std::shared_ptr<Value>, plus,
    	(virtual_<std::shared_ptr<Value> CONSTREF>, virtual_<std::shared_ptr<Value> CONSTREF>));
    	
    declare_method(std::string, str,
    	(virtual_<std::shared_ptr<Value> CONSTREF>));
    
    define_method(std::shared_ptr<Value>, plus,
    	(std::shared_ptr<Value> CONSTREF a, std::shared_ptr<Value> CONSTREF b))
    {
    	throw std::runtime_error("unsupported values in plus");
    }
    
    define_method(std::shared_ptr<Value>, plus,
    	(std::shared_ptr<ScalarT<int>> CONSTREF a, std::shared_ptr<ScalarT<int>> CONSTREF b))
    {
    	return num(a->x() + b->x());
    }
    
    define_method(std::shared_ptr<Value>, plus,
    	(std::shared_ptr<ScalarT<double>> CONSTREF a, std::shared_ptr<ScalarT<double>> CONSTREF b))
    {
    	return num(a->x() + b->x());
    }
    
    define_method(std::string, str, (std::shared_ptr<Value> CONSTREF a))
    {
    	throw std::runtime_error("unsupported value in str");
    }
    
    define_method(std::string, str, (std::shared_ptr<ScalarT<int>> CONSTREF a))
    {
    	return std::to_string(a->x());
    }
    
    define_method(std::string, str, (std::shared_ptr<ScalarT<double>> CONSTREF a))
    {
    	return std::to_string(a->x());
    }
    
    int main(int argc, const char * argv[])
    {
    	yorel::yomm2::update_methods();
    	
    	auto a = num(1);
    	auto b = num(2);
    	auto c = num(3.01);
    	auto d = num(4.001);
    	std::cout << str(plus(a, b)) << "\n";
    	std::cout << str(plus(c, d)) << "\n";
    	return 0;
    }
    
  • error in runtime destructor

    error in runtime destructor

    HI @jll63,

    Thanks for the lib again, still playing with it. Seeing this error in runtime destructor, do you know what may cause this? (not repro debug build on mac, haven't done debugging it on linux server yet assuming this is something wrong related to runtime struct for certain case)

    *** Error in `./NodeServer': free(): corrupted unsorted chunks: 0x000000000155b170 *** *** Aborted at 1563204608 (unix time) try "date -d @1563204608" if you are using GNU date *** PC: @ 0x0 (unknown) *** SIGABRT (@0x3bb20000227b) received by PID 8827 (TID 0x7f8a872cf080) from PID 8827; stack trace: *** @ 0x7f8a86cb6330 (unknown) @ 0x7f8a860dfc37 gsignal @ 0x7f8a860e3028 abort @ 0x7f8a8611c2a4 (unknown) @ 0x7f8a8612882e (unknown) @ 0x698710 __gnu_cxx::new_allocator<>::deallocate() @ 0x695988 std::allocator_traits<>::deallocate() @ 0x690eee std::_Vector_base<>::_M_deallocate() @ 0x68b38f std::_Vector_base<>::~_Vector_base() @ 0x687785 std::vector<>::~vector() @ 0x687120 yorel::yomm2::detail::runtime::~runtime() @ 0x681898 yorel::yomm2::detail::update_methods() @ 0x6862f5 yorel::yomm2::update_methods() @ 0x41ebdd RunServer() @ 0x41abda main

    call stack in GDB: (gdb) bt #0 0x00007ffff6df1c37 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x00007ffff6df5028 in __GI_abort () at abort.c:89 #2 0x00007ffff6e2e2a4 in __libc_message ([email protected]=1, [email protected]=0x7ffff6f40350 "*** Error in `%s': %s: 0x%s \n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff6e3a82e in malloc_printerr (ptr=, str=0x7ffff6f404a0 "free(): corrupted unsorted chunks", action=1) at malloc.c:4998 #4 _int_free (av=, p=, have_lock=0) at malloc.c:3842 #5 0x00000000006b269a in __gnu_cxx::new_allocatoryorel::yomm2::detail::rt_method::deallocate(yorel::yomm2::detail::rt_method, unsigned long) () #6 0x00000000006b011c in std::allocator_traits<std::allocatoryorel::yomm2::detail::rt_method >::deallocate(std::allocatoryorel::yomm2::detail::rt_method&, yorel::yomm2::detail::rt_method, unsigned long) () #7 0x00000000006abcec in std::_Vector_base<yorel::yomm2::detail::rt_method, std::allocatoryorel::yomm2::detail::rt_method >::_M_deallocate(yorel::yomm2::detail::rt_method, unsigned long) () #8 0x00000000006a6703 in std::_Vector_base<yorel::yomm2::detail::rt_method, std::allocatoryorel::yomm2::detail::rt_method >::~_Vector_base() () #9 0x00000000006a2f8b in std::vector<yorel::yomm2::detail::rt_method, std::allocatoryorel::yomm2::detail::rt_method >::~vector() () #10 0x00000000006a29c6 in yorel::yomm2::detail::runtime::~runtime() () #11 0x000000000069d306 in yorel::yomm2::detail::update_methods(yorel::yomm2::detail::registry const&, yorel::yomm2::detail::dispatch_data&) () #12 0x00000000006a1d63 in yorel::yomm2::update_methods() () #13 0x0000000000413622 in main (argc=1, argv=0x7fffffffe808) at /home/shawncao/nebula/src/service/node/NodeServer.cpp:178

  • Boost download

    Boost download

    Outline

    We are using yomm2 as a dependency of our library on a range of machines, and many of them do not have boost installed by default. System administrators often do not want to install boost system wide. This makes compiling yomm2 difficult, and it would be better if yomm2 took care of its boost dependency itself. This PR implements that feature in the same way we deal with google/benchmark already.

    Comments

    • This PR raises the minimum CMake version from 3.0 to 3.5 since boost's CMake code requires it.
    • Boosts CMake code is still not officially supported, so some hacky code was required to make it work.
    • The boost dependency is "PUBLIC", meaning that depending projects also need it - it is thus installed along with yomm2.
    • I have tested this with CMake 3.5 and 3.19 on my own machine - nowhere else yet.
  • update_methods segfault if I forget a register_class

    update_methods segfault if I forget a register_class

    I enjoyed your cppcon video, and I'm having fun playing with your library - thanks!

    If I forget a define_method, I can get an error callback with set_method_call_error_handler.

    If I forget a register_class, I get a segfault during update_methods.

    I understand that it can't just magically work, and I like that it fails early ( during update_methods, which hopefully I'm calling right from the top of main ).

    Is there any way to throw, or at least abort with relavent stderr text in this case ( without significant additional expense )?

    I can provide a sample if necessary, but just removing a register_class from an example should do it.

  • CMake overhaul

    CMake overhaul

    Sorry for the pull request out of the blue. I am suggesting major changes to the CMake scripts of yomm2. First let me explain why I was motivated to make these changes

    Motivation

    When using yomm2 as a dependency, we usually employ the same technique as suggested at for googletest: Download, build and locally install yomm2 automatically during CMake configure step using ExternalProject_Add and include the result in our main build. For yomm2, it was not possible to use CMake's find_package command to include yomm2 in our build since yomm2 does not define a proper CMake package upon installation. This is only a minor inconvenience, but was enough to motivate me to work on yomm2's CMake scipts. Additionally, "benchmark" was always downloaded even when YOMM2_ENABLE_BENCHMARKS was not set to ON, which takes unnecessary time.

    Content of Pull Request

    I have mainly made two changes:

    1. Defined CMake package building instructions (install instructions) for yomm2
    2. Overhaul of how the "benchmark" dependency is pulled and built

    As for the first point, the commits are fairly short and are the best explanation of the content of my changes that I can come up with at the moment.

    For the second point, there are a few advantages to the new method of automatically downloading and building "benchmark"

    • We no longer use add_subdirectory, so a different CMAKE_BUILD_TYPE can be used (always RELEASE atm)
    • We only download "benchmark" if YOMM2_ENABLE_BENCHMARKS=ON and it is not already installed
    • Since "benchmark" is built during the configure stage, we can use find_package to include it (better encapsulation) The only disadvantage I can come up with is that we use execute_process to execute a second cmake during the configure stage. Command line settings are not automatically transferred to this nested call, but I cannot come up with a case where that would be a problem.

    Conclusion

    I believe the suggested changes make yomm2 a more complete library, as it is now a fully defined CMake package that can easily be used from user side code (like the library we're working on).

    Please let me know if you have any questions, and I will try to respond quickly!

  • Dispatch table generation?

    Dispatch table generation?

    I enjoyed your articles on the algorithms and data structures you used to generate yomm11's dispatch tables. I don't see any comparable description for yomm2, and the comparison to yomm11 suggests the internals are substantially different. If this is the case, do you expect to write an article or summary of yomm2's algorithms?

  • Update CMakeLists

    Update CMakeLists

    Add C++17 as a required feature of the library in a generic way. This should probably be sufficient to allow the library to be packaged for OSX in vcpkg.

    • minor changes for preferred way to fiddle with flags
  • cmake fixes and improvements

    cmake fixes and improvements

    Three things here:

    1. Travis
    • The script did not detect that hybrid builds were broken. That's because it didn't exit in error when intermediate steps failed.
    • I also cleaned it up a bit, now CONFIG is used to specify all configurations (i.e. also the hybrid ones).
    • I added a dimension to the build matrix: with or without Boost pre-installed.
    • At the end, I run make install, and check that Boost libs were also installed if they were not already available. I don't know why, but installing does not work for hybrid builds so I skip this step in that case. To be investigated.
    1. Hybrid builds were broken after the auto-fetch work. My fix involves a few symlinks. If you have a better solution, please tell me.
    2. I moved the dependencies directory to the build area. It seems much cleaner to me, some users want to keep their source tree entirely free of artifacts. It leads to redundant downloads when building several configurations, but the cost is not huge and we don't run cmake that frequently. It also makes testing cmake related work easier, as deleting the build dir suffices to start again from scratch (a couple of times I forgot to rm dependencies and puzzled over the output).
  • Dispatch on arbitrary values

    Dispatch on arbitrary values

    Hello and thanks for the wonderful library.

    Is there any way to dispatch on arbitary values, not just types? Coming from a clojure background, I am trying to replicate some of the behaviour of clojures multimethods.

    In clojure the method declaration takes a function some_fn and before dispatching, it calls some_fn(arg1,args2, ...) and then dispatches based on the return value of that function.

    This enables for example dispatching on certain values in the argument and adding new behaviour later based on these fields.

    Some pseudo code of what I wanted to write:

    struct Customer{
      //some fields
      int accessLevel;
    };
    
    declare_method(std::string, purchase_rare_item, [](Customer& c){return c.accessLevel;});
    
    define_method(std::string, purchase_rare_item, default) {
        return "not allowed";
    }
    
    define_method(std::string, purchase_rare_item, 4) {
        return "please refer to the VIP auction page"
    }
    
    define_method(std::string, purchase_rare_item, 5) {
        return "thank you for your purchase."
    }
    
    

    The alternative would be to write a closed switch.

    My current workaround idea is just to create a lot of classes, so I can have the type dispatch. But it gets quite ugly. I would like for example to dispatch on whatever is the first item in a std::vector and I feel bad creating subtypes of that. Or is your advice to just go with this?

    What if the existing class I want to dispatch on has no virtual functions? Should I just wrap them in one with for example a virtual destructor?

  • Boost 1.53 compatibility

    Boost 1.53 compatibility

    First off, I realize that yomm2 dependencies clearly state that Boost 1.65 or later is recommended. However, the supercomputers which our library is intended to be used on have older versions installed, specifically 1.54 on TSUBAME and 1.53 on ABCI. Supercomputers having old library versions installed is a sad fact of the field.

    Poblem

    The issue is, Boost 1.53/1.54 do not have boost/preprocessor/tuple/push_front.hpp yet. It was added 1.56 (ouch, so close...).

    That header only contains the following definition

    # include <boost/preprocessor/array/push_front.hpp>
    # include <boost/preprocessor/array/to_tuple.hpp>
    # include <boost/preprocessor/tuple/to_array.hpp>
    
    # define BOOST_PP_TUPLE_PUSH_FRONT(tuple, elem) \
        BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_PUSH_FRONT(BOOST_PP_TUPLE_TO_ARRAY(tuple), elem)) \
    /**/
    

    This is a simple convenience routine transforming the tuple into an array, using array's push_front to add an element, and finally transforming the resulting array back into a tuple. If I simply replace BOOST_PP_TUPLE_PUSH_FRONT with its definition and include the additional headers, I can compile yomm2 with the old boost version without issues.

    Suggestion

    Use new header if available (check Boost version). If not available, define the needed function.

    #if Boost_VERSION_MINOR >= 56
    #include <boost/preprocessor/tuple/push_front.hpp>
    #else
    #include <boost/preprocessor/array/push_front.hpp>
    #include <boost/preprocessor/array/to_tuple.hpp>
    #include <boost/preprocessor/tuple/to_array.hpp>
    #define BOOST_PP_TUPLE_PUSH_FRONT(tuple, elem) BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_PUSH_FRONT(BOOST_PP_TUPLE_TO_ARRAY(tuple), elem))
    #endif
    

    I realize this is somewhat ugly and might not be something you want to include, but it would help greatly in my case since compiling a newer boost version as a non-root user is significant effort. We don't want to force users of our library on supercomputers to build boost first and fiddle around with paths. Moving back to yomm11 is an option for us, but we would like to avoid that.

  • Support shared library builds

    Support shared library builds

    • Support shared library builds of yomm2 via CMake option YOMM2_SHARED
    • If shared library build is on, force hidden visibility on *nix which greatly reduces .so size
An open-source C++ library developed and used at Facebook.

Folly: Facebook Open-source Library What is folly? Folly (acronymed loosely after Facebook Open Source Library) is a library of C++14 components desig

Nov 23, 2022
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VS

Dec 1, 2022
An open source library for C

Homo Deus - C Library Introduction The Homo Deus C Library (hdelibc) is an open source collection of tools for the C programming language. The project

Nov 28, 2022
FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.
FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.

FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.

Nov 17, 2022
Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout.
Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout.

Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout. This is the Miryoku implementation for QMK.

Nov 23, 2022
Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout
Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout

Miryoku is an ergonomic, minimal, orthogonal, and universal keyboard layout. Miryoku KMonad is the Miryoku implementation for KMonad.

Nov 25, 2022
Open multi-methods for C++11

YOMM11 IS DEPRECATED Thank you for the stars and the feedback! In 2017 I learned the D language, and I implemented an open method library for D. In th

Nov 14, 2022
Fast and Light-weight path smoothing methods for vehicles
Fast and Light-weight path smoothing methods for vehicles

path_smoother About Fast and Light-weight path smoothing methods for vehicles Denpendencies This project has been tested on Ubuntu 18.04. sudo apt-get

Dec 1, 2021
A fast multi-producer, multi-consumer lock-free concurrent queue for C++11

moodycamel::ConcurrentQueue An industrial-strength lock-free queue for C++. Note: If all you need is a single-producer, single-consumer queue, I have

Dec 1, 2022
A fast multi-producer, multi-consumer lock-free concurrent queue for C++11

moodycamel::ConcurrentQueue An industrial-strength lock-free queue for C++. Note: If all you need is a single-producer, single-consumer queue, I have

Dec 2, 2022
Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform AAA Open 3D Engine
Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform AAA Open 3D Engine

Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations.

Nov 24, 2022
std::tuple like methods for user defined types without any macro or boilerplate code

Boost.PFR This is a C++14 library for very basic reflection that gives you access to structure elements by index and provides other std::tuple like me

Nov 22, 2022
Modding (hacking) il2cpp games by classes, methods, fields names.

ByNameModding Modding (hacking) il2cpp games by classes, methods, fields names. Status: Ready to use Why did I do it 1. In order not to update the off

Nov 20, 2022
Class containing Anti-RE, Anti-Debug and Anti-Hook methods. Made for C++/CLI

Umium Class containing Anti-RE, Anti-Debug and Anti-Hook methods. Easy to use and easy to implement. Disclaimer This code has been made and optimized

Nov 26, 2022
A library of type safe sets over fixed size collections of types or values, including methods for accessing, modifying, visiting and iterating over those.

cpp_enum_set A library of type safe sets over fixed size collections of types or values, including methods for accessing, modifying, visiting and iter

Jun 16, 2022
(R) Efficient methods and operators for the sparse matrix classes in 'Matrix' (esp. CSR format or "RsparseMatrix")

MatrixExtra MatrixExtra is an R package which extends the sparse matrix and sparse vector types in the Matrix package, particularly the CSR or Rsparse

Aug 29, 2022
numerical optimizaiton methods with msnhnet

Numerical Optimization with Msnhnet. Algorithms: Unconstrained Methods Steepest Descent Newton Damped Newton Newton Levenberg Marquardt Quasi Newton (

May 22, 2022
A C++17 library of computationally efficient methods for calculating sample statistics
A C++17 library of computationally efficient methods for calculating sample statistics

Vectorized statistics using SIMD primitives Introduction is a C++17 library of computationally efficient methods for calculating sample statistics (me

Nov 20, 2022
A framework to monitor and improve the performance of PostgreSQL using Machine Learning methods.
A framework to monitor and improve the performance of PostgreSQL using Machine Learning methods.

pg_plan_inspector pg_plan_inspector is being developed as a framework to monitor and improve the performance of PostgreSQL using Machine Learning meth

Nov 27, 2022