Giter VIP home page Giter VIP logo

nontype_functional's Introduction

nontype<functional>

GitHub tag GitHub license CMake

Provide complete implementation of std::function, std::function_ref, and std::move_only_function equivalent to those in the C++23 <functional> header.

Highlights

  • Macro-free implementation
  • The size of each specialization is two pointers
  • Not require RTTI
  • Support classes without operator()

The implementation does not guarantee the best performance under all use cases but provides adequate code size & quality while maintaining full conformance.1

Supported toolchains

Toolset Standard Library Test Environment
GCC >= 11.1.0 libstdc++ Ubuntu 20.04
MSVC >= 14.30 Microsoft STL Visual Studio 2022

Installation

It's a header-only library. You may also install and consume its CMake targets:

find_package(nontype_functional CONFIG REQUIRED)
target_link_libraries("main" PRIVATE std23::nontype_functional)

Getting started

#include <std23/function_ref.h>

using std23::function_ref;

void parse_ini(function_ref<size_t(char *, size_t)> read_cb);

...

#include <stdio.h>

int main()
{
    auto fp = ::fopen("my.ini", "r");
    parse_ini([fp](auto ptr, auto n)
              { return ::fread(ptr, 1, n, fp); });
    ::fclose(fp);
}

Ignore the fact that the code has no error handling or resource-safety; the callable wrappers, function_ref in the example, generalized the idea of callbacks. You can pass anything with a matching call pattern to another function, parse_ini in here, without turning the latter into a template.

Now, what if you have an existing class that can read data, but it's not a function object?

class data_source
{
    ...

  public:
    auto read(char *, size_t) -> size_t;
};

Then you may designate a named member function, read in this example, to serve the role of an operator():

using std23::nontype;

int main()
{
    data_source input;
    parse_ini({nontype<&data_source::read>, input});
}

The nontype tag generalized the idea of delegates from other languages, like C♯. What replaces operator() doesn't have to be a member function. You can also use a free function or even a lambda:

int main()
{
    auto fp = ::fopen("my.ini", "r");
    parse_ini({nontype<[](FILE *fh, auto ptr, auto n)
                       { return ::fread(ptr, 1, n, fh); }>,
               fp});
    ::fclose(fp);
}

Feels like creating a member function for FILE on the fly, isn't it?

Roadmap

  • 0.8 – std::function_ref & std::function
  • 0.9 – std::move_only_function
  • 1.0 – nontype_t constructors for move_only_function
  • 1.1 – copyable_function from P2548
  • 1.2 – Support C++20 modules

See also

cppreference page for std::function
cppreference page for std::move_only_function
std::function_ref specification

Footnotes

  1. Except for std::function's target() member function, which is unimplemented because it requires RTTI.

nontype_functional's People

Contributors

hackmd-deploy avatar zhihaoy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nontype_functional's Issues

Please add a license

While this may be just a reference implementation not intended to be used directly (I assume?), it would still be nice to have a license to make it clear whether it is valid to copy code out of this repo or not.

Thank you!

No CTAD for lambdas & function objects

Compile the code:

    struct s1 { static int f(int) { return 0; } };
    struct s2 { int operator()(int) const { return 0; } } S2;
    auto l1 = [](int) { return 0; };

    std::function sf1 = &s1::f;      // works
    std::function sf2 = S2;          // works
    std::function sf3 = l1;          // works

    std23::function_ref f1 = &s1::f; // works
    std23::function_ref f2 = S2;     // doesn't work
    std23::function_ref f3 = l1;     // doesn't work

Expected

Successful compilation in all 3 cases, same as std::function above.

Actual

Only the first case works.

2nd:

error: class template argument deduction failed:
error: no matching function for call to 'function_ref(main()::s2&)'

3rd:

error: class template argument deduction failed:
error: no matching function for call to 'function_ref(main()::<lambda(int)>&)'

Compiler Explorer:

https://godbolt.org/z/rsc1ndjoh

Is it by design / overlook? As mentioned, std::function supports all these cases.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.