A tiny metaprogramming library

Related tags

Miscellaneous meta
Overview

Meta: A tiny metaprogramming library

Build Status

Meta is a tiny and header-only C++11 metaprogramming library released under the Boost Software License. Supported compilers are clang >= 3.4 and gcc >= 4.9. To compile with meta you just have to:

#include <meta/meta.hpp>

You can find documentation online here.

For a quick start see Eric Niebler's blog post: A tiny metaprogramming library. (Note: the names in Meta are different from those describe in the blog post, but the overall design remains the same.)

To generate the up-to-date tutorial and documentation run make doc in the build directory (requires Doxygen, LaTeX, dvips, ghostscript).

Comments
  • Improve the performance of meta::unique with meta::set.

    Improve the performance of meta::unique with meta::set.

    New components

    set<Ts...>,

    The data structure of set is essentially an inverse tree via inheritance, where the root is at the bottom and inherits from all of the children. A membership check then relies on std::is_base_of to check if a child is a base of the root. i.e. exists in the set.

    in<Set, T>

    Adds a new specialization for in: in<set<Set...>, T>.

    insert_back<Set, T>

    The behavior of insert_back is such that T is inserted to Set iff T does not already exist in Set.

    unique<List>

    Performs foldl over List performing insert_back starting from set<> to build up a unique set of types. We then convert it back to a list using as_list.

    Performance

    I ran tests for the worst case scenario for unique which is when the list is already unique.

    The generated program looks like this:

    #include <type_traits>
    #include "meta.hpp"
    
    class T0 {};
    class T1 {}; 
    /* ... */
    class Tn {}; 
    
    static_assert(std::is_same<unique<list<T0, T1, ... Tn>>, list<T0, T1, ... Tn>>::value, ""); 
    
    int main() {}
    

    The following are numbers that I observed from my Macbook Retina Pro, using clang-3.5.

    Before

    | # of types | seconds | | --- | --- | | 100 | 0.24 | | 200 | 1.32 | | 300 | 4.14 | | 400 | 9.39 | | 500 | 19.59 | | 600 | ... |

    After

    | # of types | seconds | | --- | --- | | 100 | 0.07 | | 200 | 0.17 | | 300 | 0.34 | | 400 | 0.56 | | 500 | 0.85 | | 600 | 1.24 | | 700 | 1.65 | | 800 | 2.24 | | 900 | 2.81 | | 1000 | 3.47 | | 1500 | 8.3 | | 2000 | 17.15 |

    I was hoping that std::is_base_of is performed as a constant time look-up in the compiler implementation but maybe it's not (I haven't looked), since I still observe quadratic growth with my implementation. But at least it seems to be a much lower curve.

    opened by mpark 29
  • Something is wrong with the meta travis builds

    Something is wrong with the meta travis builds

    Seems to be related to the biicode part of the travis.yml file in after_success. I guess it doesn't like being called by multiple jobs on each build. @Manu343726 could you take a look?

    opened by gnzlbg 20
  • Organize functionality in categories for the doxygen documentation

    Organize functionality in categories for the doxygen documentation

    This commit

    • puts the placeholders in the meta::placeholders namespace (they are automatically included in the meta namespace, but this allows one to easily include the placeholders without including all of meta).
    • adds more examples to the user guide (partial application, logical operations, lambdas, typical operations on lists, and brief overview of functionality).
    • merges back the workarounds into a single file.
    • organizes the functionality in the doxygen documentation as follows:
      • Metafunctions
        • Invocation
        • Composition
      • Logical
      • Algorithms
        • Query/search
        • Transformation
      • Datatype
        • List
        • Integral constant
      • Math

    Each section of the documentation contains a lazy subcategory with the corresponding metafunctions.

    opened by gnzlbg 17
  • biicode support

    biicode support

    This PR adds support for biicode, a C and C++ dependency manager. I tried to keep changes simple:

    • biicode.conf file: Think of it as the .travis.yml of biicode. It contains the settings of the biicode block. A block is like a package, the unit of code publishing of biicode.
    • .travis.yml file: The travis build is used to publish your changes to biicode automatically, you don't have to worry about the biicode block anymore.
    • CMakeLists.txt: A simple if(BIICODE) which adds the same compiler options for the target bii uses to represent the library.
    • readme.md: biicode block badge.

    Note my fork works on a biicode block using my account (Here's the block), only to serve as a proof of concept. I expect you to sign in into biicode and use your own account. I have no problem if you want to rely on me to maintain the block, but then the travis based publish will not work since encryption does not work across PRs.

    The next obvious step is to use this to decouple Meta development from Range. The work is almost done, see.

    opened by Manu343726 16
  • Add inital support for lambda

    Add inital support for lambda

    I added some initial support for lambda expressions. It needs more tests.

    I could also add more support later on for things like lazy_quote(so you can quote a metafunction inside of a placeholder expression). Or perhaps it might be better to have _args placeholder to replace all arguments instead.

    opened by pfultz2 15
  • MSVC2013 support?

    MSVC2013 support?

    I know it's a long shot, since I see now newer versions use inline namespaces and constexpr, and I appreciate the desire to keep this lightweight, but it would be tremendously useful to be able to use this in VC2013 (which lacks at least those two things)

    opened by rpavlik 10
  • Updated documentation and readme

    Updated documentation and readme

    • moved the tuple_cat example into the example directory
    • commented the tuple_cat example
    • added examples to the doxygen documentation
    • added small tutorial sections for metafunctions, metafunction classes, type lists, and metafunction composition.
    • enabled travis (updated also CMakeLists.txt with -std=c++11)
    opened by gnzlbg 8
  • Merge the three streams of meta:

    Merge the three streams of meta:

    • meta
    • range-v3
    • cmcstl2

    Details:

    • Modernize cmake a bit, add support for MSVC/clang-cl.

    • Update CI config from range-v3, add MSVC to appveyor.

    • C++20-ify requires-clauses.

    • Armor Integral concept against non-constant expressions.

    • Don't constraint all arguments of the concept implementations of and_, or_, which causes instantation defeating the short-circuiting.

    • Implement and_v and or_v variable template forms of and_c and or_c.

    • detail::count_: remove unused third template parameter.

    opened by CaseyCarter 7
  • Merged latest range-v3 changes

    Merged latest range-v3 changes

    This merges some of the latest changes.

    I've explicitly left out the:

    #ifndef nil
    using nil = nil_;
    #endif
    

    since if nil is a macro that people define often (for whatever reason) meta should probably use nil_ internally anyways.

    The libc++ specific workarounds are in the meta/meta_libcxx_workaround.hpp file (I had to add a forward declaration for std::allocator).

    • The FindMeta.cmake file allows to find the meta library automatically in the systems include dir. If not found, it gets the meta library directly from github and configures it as an external project.
    • The meta/meta_fwd.hpp file includes forward declarations used by range_fwd.hpp in range-v3.
    opened by gnzlbg 7
  • Unable to compile

    Unable to compile

    Cmake works fine..

    but during compilation:

    /home/robotserver/meta/example/tutorial_snippets.cpp:268:5: error: static assertion failed: static_assert(std::is_same<meta::invoke<t, unsigned>, int const &>{}, "");

    opened by soulslicer 5
  • Replace meta::eval with meta::_t, add meta::_v

    Replace meta::eval with meta::_t, add meta::_v

    I've long been bothered by meta's use of eval to do something as trivial as typename T::type. I would rather use eval to evaluate deferred expressions (currently achieved by doing a let without any argument bindings, which reads a bit awkwardly IMO). Besides, since meta doesn't trade in metafunctions the way MPL does, it's wrong to encourage users to think of accessing a nested type as "evaluating" anything.

    Until recently, I couldn't think of a better name for the thing eval does. But how about this:

    template <typename T>
    using _t = typename T::type;
    
    template <typename T>
    constexpr typename T::type::value_type _v = T::type::value;
    

    This introduces _t as fetching a nested ::type and _v as fetching a nested ::value. These are obviously intended to evoke the xxx_t and xxx_v traits and variable templates in <type_traits>.

    @gnzlbg, thoughts?

    opened by ericniebler 5
  • Tests do not compile with Clang 10+ because of `-Wxor-used-as-pow` (enabled by default)

    Tests do not compile with Clang 10+ because of `-Wxor-used-as-pow` (enabled by default)

    FAILED: meta/test/CMakeFiles/test.meta.dir/meta.cpp.o
    /usr/bin/clang++  -I/mnt/c/Users/Вова/projects/cpp-project-template/meta/include -std=c++11 -ftemplate-backtrace-limit=0 -Weverything -Werror -pedantic-errors -Wdocumentation -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-old-style-cast -Wno-documentation-unknown-command -Wno-missing-prototypes -O2 -g -DNDEBUG -fcolor-diagnostics -MD -MT meta/test/CMakeFiles/test.meta.dir/meta.cpp.o -MF meta/test/CMakeFiles/test.meta.dir/meta.cpp.o.d -o meta/test/CMakeFiles/test.meta.dir/meta.cpp.o -c '/mnt/c/Users/Вова/projects/cpp-project-template/meta/test/meta.cpp'
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/test/meta.cpp:1966:45: error: result of '10 ^ 15' is 5; did you mean '1e15'? [-Werror,-Wxor-used-as-pow]
            static_assert(std::is_same<int_<(10 ^ 15)>, bit_xor<int_<10>, int_<15>>>::value, "");
                                             ~~~^~~~
                                             1e15
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/test/meta.cpp:1966:45: note: replace expression with '0xA ^ 15' or use 'xor' instead of '^' to silence this warning
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/test/meta.cpp:2101:39: error: result of '10 ^ 15' is 5; did you mean '1e15'? [-Werror,-Wxor-used-as-pow]
                    std::is_same<int_<(10 ^ 15)>, let<lazy::bit_xor<int_<10>, int_<15>>>>::value, "");
                                       ~~~^~~~
                                       1e15
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/test/meta.cpp:2101:39: note: replace expression with '0xA ^ 15' or use 'xor' instead of '^' to silence this warning
    2 errors generated.
    
    opened by b1ackviking 0
  • Compilation errors with `-Werror -Wold-style-cast`

    Compilation errors with `-Werror -Wold-style-cast`

    When compiling an empty program like this

    #include <meta/meta.hpp>
    int main() {}
    

    The following compilation errors come from the header file:

    FAILED: CMakeFiles/cpp-project-template.dir/main.cpp.o
    /usr/bin/c++  -I/mnt/c/Users/Вова/projects/cpp-project-template/meta/include -O2 -g -DNDEBUG -fdiagnostics-color=always -Wall -Wextra -Wpedantic -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual -Wconversion -Wsign-conversion -Wnull-dereference -Wdouble-promotion -Wformat=2 -Werror -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wuseless-cast -std=gnu++2a -MD -MT CMakeFiles/cpp-project-template.dir/main.cpp.o -MF CMakeFiles/cpp-project-template.dir/main.cpp.o.d -o CMakeFiles/cpp-project-template.dir/main.cpp.o -c '/mnt/c/Users/Вова/projects/cpp-project-template/main.cpp'
    In file included from /mnt/c/Users/Вова/projects/cpp-project-template/main.cpp:1:
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/include/meta/meta.hpp:2657:53: error: use of old-style cast to ‘std::size_t’ {aka ‘long unsigned int’} [-Werror=old-style-cast]
     2657 |             using type = meta::size_t<((std::size_t)_v<std::is_same<T, Ts>> + ...)>;
          |                                                     ^~~~~~~~~~~~~~~~~~~~~~~
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/include/meta/meta.hpp:2733:80: error: use of old-style cast to ‘bool’ [-Werror=old-style-cast]
     2733 |             using type = meta::size_t<((std::size_t)(bool)invoke<Fn, L>::type::value + ...)>;
          |                                                                                ^~~~~
    /mnt/c/Users/Вова/projects/cpp-project-template/meta/include/meta/meta.hpp:2733:80: error: use of old-style cast to ‘std::size_t’ {aka ‘long unsigned int’} [-Werror=old-style-cast]
    
    opened by b1ackviking 0
  • clang 10.0 compiler error

    clang 10.0 compiler error

    I get a compile error with clang 10.0:

    meta/meta_fwd.hpp:286:20: error: expected concept name with optional arguments
    [build]         { T{} } -> typename T::value_type;
    [build]                    ^
    

    Whats the fix?

    opened by gabyx 2
  • Fix reverse_fold without concepts

    Fix reverse_fold without concepts

    I believe there's an error in the reverse_fold implementation in case META_CONCEPT is not set. compose1_ as defined by fold passes the functor's argument as the first argument to the function. Where compose1_ is used in the implementation of reverse_fold, I believe we want to pass it on as the second function argument. Anyway, that's how I interpret Fun(A_N, State_N+1) in the documentation.

    Without this change, I get

    In file included from examples/calc/calc.cc:1:
    meta/include/meta/meta.hpp:141:5: error: no type named 'type' in 'meta::detail::reverse_fold_<meta::list<…>, meta::list<>, (anonymous namespace)::CollectProductions<(anonymous namespace)::Expr> >'
        using _t = typename T::type;
        ^~~~~
    

    My compiler is

    $ c++ --version
    Apple LLVM version 10.0.1 (clang-1001.0.46.4)
    Target: x86_64-apple-darwin18.6.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    
    opened by jkuebart 1
Owner
Eric Niebler
Member of the ISO C++ Standardization Committee and principal author of the Ranges TS (now `std::ranges`).
Eric Niebler
Intuitive & Powerful C++20 consteval metaprogramming library(via value).

meta-list This library provides a bunch of consteval toolsets to do metaprogramming, and provides the pipeline syntactic sugar for function combinatio

Netcan 35 Oct 21, 2022
This project contains a library for C++ AST parsing, metaprogramming and reflection

Meta C++ This project contains a library for C++ AST parsing, metaprogramming and reflection. Also included is a tool for generating the necessary met

Keith Hammond 76 Oct 14, 2022
Tiny - low-level library for minimizing the size of your types

foonathan/tiny Note: This project is currently WIP, no guarantees are made until an 0.1 release. This project is a C++11 library for putting every las

Jonathan Müller 101 Oct 29, 2022
Tiny header-only library providing bitwise operators for enums in C++11

bitflags Tiny header-only library providing bitwise operators for enums in C++11. Getting started Import the operators from namespace avakar::bitflags

Martin Vejnár 3 Aug 28, 2022
JoyfulNoise Tiny Utility Board

JoyfulNoise Tiny Utility Board A versatile ATtiny85-powered Eurorack module in 4HP. License JoyfulNoise hardware and software is Open Source. The JNTU

Ben Reeves 22 Jul 25, 2022
Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6

Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6. It is designed for microcontroller development. Instead of writing firmware code in C/C++, Elk allows to develop in JavaScript. Another use case is providing customers with a secure, protected scripting environment for product customisation.

Cesanta Software 1.4k Nov 14, 2022
Tiny FEL tools for allwinner SOC, support RISC-V D1 chip

XFEL Tiny FEL tools for allwinner SOC, support RISC-V D1 chip. How to build The xfel tools depends on the libusb-1.0 library, you need to install libu

xboot.org 123 Nov 11, 2022
A tiny external monitor for PC using STM32 and ST7789. Connects to PC over USB and displays the captured screen on ST7789 (240x240) display.

STM32 Tiny Monitor A super tiny monitor for your PC, suitable for your pet ant. A python script sends the captured screen over USB to the STM32 microc

Avra Mitra 68 Nov 16, 2022
Tiny weather station based on TTGO T5 V2.3.1 (ESP32 with 2.13

Tiny weather station based on TTGO T5 V2.3.1 (ESP32 with 2.13" e-ink display) Features wireless and rechargable weather description including temperat

Piotr Kubica 17 Apr 3, 2022
A tiny Forth I built in a week.

( Wrote a blog post about this here ) It was raining hard, a week ago. And what could you possibly do on a rainy Saturday afternoon? Well... You can m

Thanassis Tsiodras 67 Oct 4, 2022
Retro Tiny Multitasking system for Z80 based computers

RTM-Z80 RTM/Z80 is a multitasking kernel, built for Z80 based computers, written in Z80 assembly language, providing its users with an Application Pro

ladislau szilagyi 103 Nov 9, 2022
Tiny and cheap robot car for inspecting sewer pipes >= 125 mm. With pan servo for the ESP32-Cam module

ESP32-Cam Sewer inspection car Version 1.0.0 - work in progress Based on esp32-cam-webserver by Owen Carter. Additional Features Pan servo for the ESP

Armin 5 Nov 6, 2022
Tiny and portable usb host and device stack for mcu with usb ip

Tiny and portable usb host and device stack for mcu with usb ip

sakumisu 501 Nov 18, 2022
Love 6's Regular Expression Engine. Support Concat/Select/Closure Basic function. Hope u can enjoy this tiny engine :)

Regex_Engine Love 6's Blog Website: https://love6.blog.csdn.net/ Love 6's Regular Expression Engine Hope u can love my tiny regex engine :) maybe a fe

Love6 2 May 24, 2022
A tiny evolution simulator, which uses SDL2 and is written in C

evosim Evosim is a small evolution simulator. Evosim uses the SDL2 library for graphics. The program can be compiled by simply running make in the evo

Victor Ocampo 2 Nov 20, 2021
Tiny C++ State Machine Implementation in C++

Overview This is a tiny C++ API for writing state machines. It consists of a single header with a single class StateMachine. Users must define their S

Matthew Saltz 8 Jan 18, 2022
Second life for famous JPEGView - fast and tiny viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimalist GUI and base image processing.

JPEGView-Image-Viewer-and-Editor Updated Dec 07 2021. Version 1.1.1.0 has been released. Download link1, link2 added. Second life for famous JPEGView

Ann Hatt 35 Nov 4, 2022
Tiny blocker of Windows tracking and telemetry written in plain C++/Win32 API.

Tiny blocker of Windows tracking and telemetry written in plain C++/Win32 API. Just run once as admin and forget. No questions asked. No harmful actions performed like other Windows spying blockers try.

null 5 Mar 30, 2022