Improved and configurable drop-in replacement to std::function that supports move only types, multiple overloads and more

Overview

fu2::function an improved drop-in replacement to std::function

Build Status Build status

Provides improved implementations of std::function:

  • copyable fu2::function
  • move-only fu2::unique_function (capable of holding move only types)
  • non-owning fu2::function_view (capable of referencing callables in a non owning way)

that provide many benefits and improvements over std::function:

  • const, volatile, reference and noexcept correct (qualifiers are part of the operator() signature)
  • convertible to and from std::function as well as other callable types
  • adaptable through fu2::function_base (internal capacity, copyable and exception guarantees)
  • overloadable with an arbitrary count of signatures (fu2::function<bool(int), bool(float)>)
  • full allocator support in contrast to std::function, which doesn't provide support anymore
  • covered by many unit tests and continuous integration services (GCC, Clang and MSVC)
  • header only, just copy and include function.hpp in your project
  • permissively licensed under the boost license

Table of Contents

Documentation

How to use

function2 is implemented in one header (function.hpp), no compilation is required. Just copy the function.hpp header in your project and include it to start. It's recommended to import the library as git submodule using CMake:

# Shell:
git submodule add https://github.com/Naios/function2.git
# CMake file:
add_subdirectory(function2)
# function2 provides an interface target which makes it's
# headers available to all projects using function2
target_link_libraries(my_project function2)

Use fu2::function as a wrapper for copyable function wrappers and fu2::unique_function for move only types. The standard implementation std::function and fu2::function are convertible to each other, see the chapter convertibility of functions for details.

A function wrapper is declared as following:

fu2::function<void(int, float) const>
// Return type ~^   ^     ^     ^
// Parameters  ~~~~~|~~~~~|     ^
// Qualifier ~~~~~~~~~~~~~~~~~~~|
  • Return type: The return type of the function to wrap.
  • Arguments: The argument types of the function to wrap. Any argument types are allowed.
  • Qualifiers: There are several qualifiers allowed:
    • no qualifier provides ReturnType operator() (Args...)
      • Can be assigned from const and no const objects (mutable lambdas for example).
    • const provides ReturnType operator() (Args...) const
      • Requires that the assigned functor is const callable (won't work with mutable lambdas),
    • volatile provides ReturnType operator() (Args...) volatile
      • Can only be assigned from volatile qualified functors.
    • const volatile provides ReturnType operator() (Args...) const volatile
      • Same as const and volatile together.
    • r-value (one-shot) functions ReturnType operator() (Args...) &&
      • one-shot functions which are invalidated after the first call (can be mixed with const, volatile and noexcept). Can only wrap callable objects which call operator is also qualified as && (r-value callable). Normal (C) functions are considered to be r-value callable by default.
    • noexcept functions ReturnType operator() (Args...) noexcept
      • such functions are guaranteed not to throw an exception (can be mixed with const, volatile and &&). Can only wrap functions or callable objects which call operator is also qualified as noexcept. Requires enabled C++17 compilation to work (support is detected automatically). Empty function calls to such a wrapped function will lead to a call to std::abort regardless the wrapper is configured to support exceptions or not (see adapt function2).
  • Multiple overloads: The library is capable of providing multiple overloads:
    fu2::function<int(std::vector<int> const&),
                  int(std::set<int> const&) const> fn = [] (auto const& container) {
                    return container.size());
                  };

Constructing a function

fu2::function and fu2::unique_function (non copyable) are easy to use:

fu2::function<void() const> fun = [] {
  // ...
};

// fun provides void operator()() const now
fun();

Non copyable unique functions

fu2::unique_function also works with non copyable functors/ lambdas.

fu2::unique_function<bool() const> fun = [ptr = std::make_unique<bool>(true)] {
  return *ptr;
};

// unique functions are move only
fu2::unique_function<bool() const> otherfun = std::move(fun):

otherfun();

Non owning functions

A fu2::function_view can be used to create a non owning view on a persistent object. Note that the view is only valid as long as the object lives.

auto callable = [ptr = std::make_unique<bool>(true)] {
  return *ptr;
};

fu2::function_view<bool() const> view(callable);

Convertibility of functions

fu2::function, fu2::unique_function and std::function are convertible to each other when:

  • The return type and parameter type match.
  • The functions are both volatile or not.
  • The functions are const correct:
    • noconst = const
    • const = const
    • noconst = noconst
  • The functions are copyable correct when:
    • unique = unique
    • unique = copyable
    • copyable = copyable
  • The functions are reference correct when:
    • lvalue = lvalue
    • lvalue = rvalue
    • rvalue = rvalue
  • The functions are noexcept correct when:
    • callable = callable
    • callable = noexcept callable
    • noexcept callable = noexcept callable
Convertibility from \ to fu2::function fu2::unique_function std::function
fu2::function Yes Yes Yes
fu2::unique_function No Yes No
std::function Yes Yes Yes
fu2::function<void()> fun = []{};
// OK
std::function<void()> std_fun = fun;
// OK
fu2::unique_function<void()> un_fun = fun;

// Error (non copyable -> copyable)
fun = un_fun;
// Error (non copyable -> copyable)
fun = un_fun;

Adapt function2

function2 is adaptable through fu2::function_base which allows you to set:

  • IsOwning: defines whether the function owns its contained object
  • Copyable: defines if the function is copyable or not.
  • Capacity: defines the internal capacity used for sfo optimization:
struct my_capacity {
  static constexpr std::size_t capacity = sizeof(my_type);
  static constexpr std::size_t alignment = alignof(my_type);
};
  • IsThrowing defines if empty function calls throw an fu2::bad_function_call exception, otherwise std::abort is called.
  • HasStrongExceptGuarantee defines whether the strong exception guarantees shall be met.
  • Signatures: defines the signatures of the function.

The following code defines an owning function with a variadic signature which is copyable and sfo optimization is disabled:

template<typename Signature>
using my_function = fu2::function_base<true, true, fu2::capacity_none, true, false, Signature>;

The following code defines a non copyable function which just takes 1 argument, and has a huge capacity for internal sfo optimization. Also it must be called as r-value.

template<typename Arg>
using my_consumer = fu2::function_base<true, false, fu2::capacity_fixed<100U>,
                                       true, false, void(Arg)&&>;

// Example
my_consumer<int, float> consumer = [](int, float) { }
std::move(consumer)(44, 1.7363f);

Performance and optimization

Small functor optimization

function2 uses small functor optimization like the most common std::function implementations which means it allocates a small internal capacity to evade heap allocation for small functors.

Smart heap allocation moves the inplace allocated functor automatically to the heap to speed up moving between objects.

It's possible to disable small functor optimization through setting the internal capacity to 0.

Coverage and runtime checks

Function2 is checked with unit tests and valgrind (for memory leaks), where the unit tests provide coverage for all possible template parameter assignments.

Compatibility

Tested with:

  • Visual Studio 2017+ Update 3
  • Clang 3.8+
  • GCC 5.4+

Every compiler with modern C++14 support should work. function2 only depends on the standard library.

License

function2 is licensed under the very permissive Boost 1.0 License.

Similar implementations

There are similar implementations of a function wrapper:

Also check out the amazing CxxFunctionBenchmark which compares several implementations.

Comments
  • Compile time bug with noexcept specifier

    Compile time bug with noexcept specifier

    @Naios

    Cannot use noexcept specifier. Looks like a compile time bug. I think something should be sfinae but its not


    Commit Hash

    last, 035bec21533f484c1b5dd8dd0380109ea431f6a1

    Expected Behavior

    Should compile

    Actual Behavior

    Don't compile

    Steps to Reproduce

    See godbolt

    Your Environment

    • OS: Arch Linux
    • Compiler and version: gcc 12.1
    bug 
    opened by MBkkt 11
  • Compiling as Objective-C++ conflict due to block pointer conversion

    Compiling as Objective-C++ conflict due to block pointer conversion

    @Naios


    Commit Hash

    7cd9537

    Expected Behavior

    Compilation works as expected

    Actual Behavior

    Compilation fails with the following error:

    .../function2.hpp:1131:14: Call to implicitly-deleted copy constructor of 'const (lambda at .../main.mm:27:25)'

    Implicit capture of lambda object due to conversion to block pointer here (1131:14, if (bool(callable)) {)

    Steps to Reproduce

    Compile the following in Xcode as a .mm file:

    #include <memory>
    #include "function2.hpp"
    
    template<typename Signature>
    using r_function = fu2::function_base<
    	true,
    	false,
    	fu2::capacity_default,
    	false,
    	false,
    	Signature
    >;
    
    int main(int argc, const char * argv[])
    {
    	std::unique_ptr<int> testInt = std::make_unique<int>(4);
    	int r_testInt = 0;
    	
    	auto parameterUpdate = [&, testInt = std::move(testInt)]()
    	{
    		if (testInt)
    		{
    			r_testInt = *testInt;
    		}
    	};
    	
    	r_function<void()> myFunc(std::move(parameterUpdate));
    	//fu2::unique_function<void()> myFunc(std::move(parameterUpdate)); //This fails too
    	
    	return 0;
    }
    

    Your Environment

    • OS: OSX
    • Compiler and version: Xcode 11.2.1, Apple Clang, compiled as C++17
    • Standard library (if non default): libc++
    wontfix 
    opened by Rajveer86 7
  • Won't compile with Visual Studio 2019 16.3, 16.2 works good.

    Won't compile with Visual Studio 2019 16.3, 16.2 works good.

    @Naios

    Error in VS 16.3:

    error C2440: 'static_cast': cannot convert from 'fu2::abi_400::detail::type_erasure::erasure<true,Config,fu2::abi_400::detail::property<true,false,void *(void *)>>' to 'erasure_t &' error C2440: with error C2440: [ error C2440: Config=fu2::abi_400::detail::config<true,false,fu2::capacity_default> error C2440: ]

    Commit Hash

    5dcbecd91b60f50560b1be055f1603f3b715b5e1

    Expected Behavior

    Should compile

    Actual Behavior

    Won't compile

    Steps to Reproduce

    Try and compile uwebsockets with Visual Studio 2019 16.3 I also created an issue here: https://github.com/uNetworking/uWebSockets/issues/940 However I think the issue only is in the function2 lib.

    Your Environment

    Windows 10, x64 Visual Studio 2019 16.3 MSVC V142

    compiler-regression 
    opened by ZeikoRomsan1 6
  • Got MSVC error C2248 when I use unique_function with boost::callable_traits::is_invocable

    Got MSVC error C2248 when I use unique_function with boost::callable_traits::is_invocable

    @Naios

    When I use fu2::unique_function with boost::callable_traits::is_invocable on msvc v19.33 or older (on godbolt) , then I got C2248 error. It doesn't happen with std::function. When I test it on msvc latest (on godbolt), no error happens. When I test it on g++ and clang++, no error happens.

    It might be msvc issue, but msvc v19.33 is not so old. If fu2::unique_function could avoid the issue, it is very helpful.


    Commit Hash

    2d3a878ef19dd5d2fb188898513610fac0a48621

    Expected Behavior

    Build finished without the error.

    Actual Behavior

    Got C2248 (cannot access private member) error.

    Steps to Reproduce

    #include <function2/function2.hpp>
    #include <boost/callable_traits.hpp>
    #include <type_traits>
    
    using std_func_t = std::function<void()>;
    using unique_func_t = fu2::unique_function<void()>;
    
    
    int main() {
        // std::function : no error
        static_assert(boost::callable_traits::is_invocable<std_func_t>::value);
        // fu2::unique_function : error C2248 on msvc v19.33 and older
        static_assert(boost::callable_traits::is_invocable<unique_func_t>::value);
    }
    

    Godbolt link Compiler|Link|Result ---|---|--- msvc v19.33|https://godbolt.org/z/PxMa4q3oo|error C2248 msvc latest|https://godbolt.org/z/bbrxb6nTe| no error clang++ 15.0.0 | https://godbolt.org/z/zPEGqbjsn | no error g++ 12.2 | https://godbolt.org/z/7Eb1hs8KW | no error

    Your Environment

    • OS: Windows
    • Compiler and version: MSVC v19.33 (godbolt)
    question 
    opened by redboltz 5
  • -Waddress warning generated for non-capturing lambdas on gcc <= 9.2

    -Waddress warning generated for non-capturing lambdas on gcc <= 9.2

    @Naios

    In gcc versions before 9.3, the compiler would generate a -Waddress warning complaining that the address of a lambda's function will never be null if it is cast to a boolean (compiler explorer), even in generic code.

    This impacts function2 because the generic logic to determine if a newly-constructed function object should be empty ends up triggering these warnings when passed a captureless lambda in various places, as it passes the use_bool_op checks:

    https://github.com/Naios/function2/blob/035bec21533f484c1b5dd8dd0380109ea431f6a1/include/function2/function2.hpp#L1158 https://github.com/Naios/function2/blob/035bec21533f484c1b5dd8dd0380109ea431f6a1/include/function2/function2.hpp#L1220 https://github.com/Naios/function2/blob/035bec21533f484c1b5dd8dd0380109ea431f6a1/include/function2/function2.hpp#L1341

    This can be seen with this example compiler explorer instance hitting the warning from each of these places: https://godbolt.org/z/vvKfonTa1

    I can't think of a practical way off the top of my head to detect non-nullable captureless lambdas in use_bool_op and treat them differently than other function-like objects which can convert to bool, so the easiest approach may be to suppress the warning on these older compiler versions. It appears that libstdc++ just manually enumerates all types which can be checked for emptyness as required by the spec (https://github.com/gcc-mirror/gcc/blob/3b3f2f7c265ef9f176cb811a8049b24538d954d9/libstdc++-v3/include/bits/std_function.h#L210-L228) which I imagine isn't a practical approach for this library.


    Commit Hash

    02ca99831de59c7c3a4b834789260253cace0ced

    Expected Behavior

    No warning is emitted when building with -Waddress

    Actual Behavior

    -Waddress warnings are emitted on gcc 9.2 and earlier when constructing or assigning a function2 function object with a captureless lambda.

    Steps to Reproduce

    Use the function2 library with gcc 9.2 or earlier, enable -Waddress warnings, and construct a function2 function object with a captureless lambda.

    Example godbolt instance: https://godbolt.org/z/vvKfonTa1

    Your Environment

    • OS: Linux (Ubuntu LTS)
    • Compiler and version: GCC 9.2 and earlier
    • Standard library (if non default): libstdc++ (default)
    bug minor 
    opened by mystor 5
  • Don't include test targets if disabled

    Don't include test targets if disabled

    @Naios


    What was a problem?

    Doing a shallow clone and attempting to build with BUILD_TESTING=OFF doesn't work due to missing files for googletest targets.

    How this PR fixes the problem?

    By not including any of the test targets if BUILD_TESTING=OFF

    opened by wak-google 5
  • Undefined std::free, std::abort and std::malloc

    Undefined std::free, std::abort and std::malloc

    If I do not include cstdlib before including the header file, I receive the following error message for std::free, std::abort and std::malloc:

    error : no member named 'abort' in namespace 'std'

    Should the header include cstdlib itself?

    question 
    opened by Rajveer86 5
  • Cannot compile with Clang with exceptions turned off

    Cannot compile with Clang with exceptions turned off

    I would like to use a self-defined version of unique_function using function_base which doesn't throw an exception, as I would prefer to use Clang's default setting of no exceptions. However, as soon as I include the header file, Clang parses it and complains that throw() isn't supported.

    Adding the -fdelayed-template-parsing flag to Clang works, however if possible I would rather not use WIP (and non-standard, according to this answer) flags.

    Is it possible to modify the header file so that it only exposes exception code if exceptions are turned on?

    bug 
    opened by Rajveer86 5
  • chore: silence Visual Studio 2022 (17.3.0) warning

    chore: silence Visual Studio 2022 (17.3.0) warning

    Starting with Visual Studio 2022 (17.3.0) the following warning is emitted:

    include\function2\function2.hpp(1176): warning C4305: '<function-style-cast>': truncation from 'bool (__cdecl *)(void)' to 'bool'
    

    Neither bool(callable) (as it was written), nor static_cast<bool>(callable) seem to make the compiler happy. It worked with either !! or omitting it completely.

    @Naios

    opened by gjasny 4
  • Allow configuring for AppleClang

    Allow configuring for AppleClang

    @Naios

    Running CMake on function2 causes a failure if you select the generator -G Xcode while on an apple mac. This is because the CMAKE_COMPILER_ID for Apple's compiler is AppleClang.


    What was a problem?

    Failure to configure when using Apple Clang.

    How this PR fixes the problem?

    Modify the check for Clang to use a regex match on "Clang" so that it captures both AppleClang and Clang

    Check lists (check x in [ ] of list items)

    • [ ] Additional Unit Tests were added that test the feature or regression
    • [ ] Coding style (Clang format was applied)

    Additional Comments (if any)

    No tests required - the test is the fact that the project now configures correctly on a mac and continues to configure correctly on other Clang environments.

    opened by madmongo1 4
  • fu2::function_view created from empty fu2::function is not itself empty

    fu2::function_view created from empty fu2::function is not itself empty

    @Naios

    Instantiating an fu2::function_view from an empty fu2::function does not produce an empty fu2::function_view. I didn't look into it too deeply but my initial impression is that it's due to the constructor for arbitrary callables function(T&& callable) getting called instead of function(function<RightConfig, property_t> const& right) as I would expect, so the erasure_t is constructed to wrap the fu2::function as a whole instead of unpacking it.


    Commit Hash

    e3695b4b4fa3c672e25c6462d7900f8d2417a417

    Steps to Reproduce

    // empty_function_view_test.cpp
    #include <catch2/catch.hpp>
    #include <function2/function2.hpp>
    
    #include <optional>
    #include <string>
    
    TEST_CASE("Function2 function -> function_view", "[function2]")
    {
        fu2::function<std::optional<size_t>(const std::string&)> f = [](const std::string &str) -> std::optional<size_t> {
            if (str.size() > 0) { return str.size(); }
            else { return std::nullopt; }
        };
        REQUIRE_FALSE(f.empty()); // pass
        fu2::function_view<std::optional<size_t>(const std::string&)> fv = f;
        REQUIRE_FALSE(fv.empty()); // pass
    
        fu2::function<std::optional<size_t>(const std::string&)> emptyf{};
        REQUIRE(emptyf.empty()); // pass
        fu2::function_view<std::optional<size_t>(const std::string&)> emptyfv = emptyf;
        REQUIRE(emptyfv.empty()); // fail
    }
    

    Your Environment

    • OS: Mac OS Mojave, Gentoo Linux
    • Compiler and version: appleclang-10.0.1, gcc-8.3
    bug 
    opened by eigenwhat 4
  • Incomprehensible error message on clang

    Incomprehensible error message on clang

    @Naios

    When trying to initialize fu2::function_view<float(float)> with an object of type fu2::function<float(float) const>, clang 14 spews out an incomprehensible error message without a proper "instantiation stack". It is possible to infer what the problem is from const T not being castable to void* inside address_taker, but I think a proper concept or static assert based error message would be much preferred.


    Commit Hash

    2d3a878ef19dd5d2fb188898513610fac0a48621

    Expected Behavior

    Pretty error message, "cannot initialize a non-const callable function view with a const-only callable function".

    Actual Behavior

    Incomprehensible error message

    Steps to Reproduce

    Try to initialize a fu2::function_view<float(float)> with an object of type fu2::function<float(float) const>

    Your Environment

    • OS: Windows
    • Compiler and version: Clang-cl 14
    • Standard library (if non default): MSVC
    opened by Mrkol 0
  • Potential null pointer dereference in Function2

    Potential null pointer dereference in Function2

    @Naios


    Commit Hash

    Function2 tags 4.2.0 and 4.2.1, hashes: 02ca99831de59c7c3a4b834789260253cace0ced f569a63cfe369df867a1a4d17aaa12269156536c

    Expected Behavior

    Test case pasted below compiles without errors with g++-11 -O1 -Wnull-dereference -c -o null-deref.o null-deref.cpp

    Actual Behavior

    Test case given below produces a warning for a null pointer dereference:

    g++-11 -O1 -Wnull-dereference   -c -o null-deref.o null-deref.cpp
    null-deref.cpp: In static member function ‘static Ret fu2::abi_400::detail::type_erasure::invocation_table::function_trait<Ret(Args ...)>::internal_invoker<T, IsInplace>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, std::size_t, Args ...) [with T = fu2::abi_400::detail::type_erasure::box<false, Foo::bar()::<lambda()>, std::allocator<Foo::bar()::<lambda()> > >; bool IsInplace = true; Ret = int; Args = {}]’:
    null-deref.cpp:14:44: warning: potential null pointer dereference [-Wnull-dereference]
       14 |     CallbackT c = std::move([=]() { return x; });
          |                                            ^
    null-deref.cpp:14:44: warning: potential null pointer dereference [-Wnull-dereference]
    

    Steps to Reproduce

    Test case file:

    //#include "function2.hpp"
    #include "function2-upstream-master.hpp"
    #include <functional>
    #include <iostream>
    //#include "function2.hpp-fixed"
    
    using namespace std;
    
    class Foo {
    public:
      using CallbackT = fu2::unique_function<int(void)>;
      void bar(void) {
        int x = 10;
        CallbackT c = std::move([=]() { return x; });
      }
    };
    
    int main(void) {
      Foo a;
      a.bar();
      return 0;
    }
    

    Compile with the command:

    g++-11 -O1 -Wnull-dereference   -c -o null-deref.o null-deref.cpp
    

    This issue can be solved by the following patch to function2.hpp

    Patch to tag 4.2.0
    --- function2.hpp	2022-06-16 19:56:34.645027778 +0000
    +++ function2.hpp-fixed	2022-06-16 15:54:34.989443571 +0000
    @@ -573,6 +573,7 @@
             auto obj = retrieve<T>(std::integral_constant<bool, IsInplace>{},      \
                                    data, capacity);                                \
             auto box = static_cast<T CONST VOLATILE*>(obj);                        \
    +       if(box == nullptr) throw_or_abort##NOEXCEPT(std::integral_constant<bool, false>{});      \
             return invocation::invoke(                                             \
                 static_cast<std::decay_t<decltype(box->value_)> CONST VOLATILE     \
                                 REF>(box->value_),                                 \
    

    Your Environment

    • OS: Linux, Ubuntu 20.04 and 22.04
    • Compiler and version: GCC 11.1.0, 11.2.0, 12.0.1 (packaged in Ubuntu)
    • Standard library (if non default): default
    opened by TheBitshifter 1
  • Use strongly typed configuration options instead of multiple bools

    Use strongly typed configuration options instead of multiple bools

    @Naios Here are some suggestions about fu2::function_base.

    1. There are too many boolean template parameters. It's hard to imagine what specific combination of policies are given if we just write
    template<typename Arg>
    using my_consumer = fu2::function_base<true, false, fu2::capacity_fixed<100U>,
                                           true, false, void(Arg)&&>;
    

    In my opinion, better alternatives might be:

    • Use separate enum types for each policy parameter, or
    • Change policy parameters from non-type parameters to type parameters, and define new empty type for each policy.

    The second approach might require more template metaprogramming, but it's open-ended (users can add more options at their will) while the enum approach is closed-ended. This might be either pros or cons, though.

    I recommend the enum approach, and I think there is virtually no downside of it compared to the boolean approach, except that the implementation might be a bit more verbose.

    1. This one is about README. I'm not sure what HasStrongExceptGuarantee is meant to mean. I mean, I know what strong exception guarantee means in general, but I think it might be better to explicitly say (1) where are the places fu2::function_base is guarding against exceptions when HasStrongExceptGuarantee is set to be true, and (2) exactly what invariants are preserved. I assumed these are about copy assignment, is that correct?

    Thanks!

    feature-request 
    opened by jk-jeon 4
  • Suggestion: Allow users of function2 to know easily whether their lambdas are stored inplace

    Suggestion: Allow users of function2 to know easily whether their lambdas are stored inplace

    @Naios Suggestion

    For example,

    using MyFunction =  fu2::function_base<...>;
    auto cb = [foo, bar] {};
    static_assert(MyFunction::is_inplace(cb), "Lambda too big!")
    

    This could be useful to maintain code over time and not to break performance-related assumptions..

    feature-request 
    opened by romange 3
  • Please add an analogue of emplace

    Please add an analogue of emplace

    @Naios

    Being able to construct an object rather than having to copy/move one in would be very useful, particularly for objects that may be expensive to construct, or (for unique_function) immovable objects. (After all, if they're on the heap we can still move the pointer.)


    Commit Hash

    7cd95374b0f1c941892bfc40f0ebb6564d33fdb9

    Expected Behavior

    Being able to type something like fun.emplace<Foo>(something, something)

    Actual Behavior

    Needing to type fun = Foo(something, something)

    Steps to Reproduce

    N/A

    Your Environment

    • OS: Fedora 30
    • Compiler and version: GCC 9.2.1
    • Standard library (if non default): libstdc++-9.2.1
    feature-request 
    opened by adamemerson 1
  • Some compiler warnings are generated

    Some compiler warnings are generated

    @Naios

    This is relatively minor, but I thought I'd mention it before I forget about them: building function2 strictly as a copied header with clang can trigger a few warnings, if you enable them.


    Commit Hash

    5b8e6de

    Expected Behavior

    Builds cleanly (no warnings).

    Actual Behavior

    Building generates warnings, as follows:

    1. An uninitialized-member warning due to member variables cmd_ and vtable_ not having default initializers and not being explicitly initialized in the default constructor for class type_erasure::tables::vtable.
    member 'cmd_' is missing from constructor initializer list [-Werror,-Wuninitialized-member]
    member 'vtable_' is missing from constructor initializer list [-Werror,-Wuninitialized-member]
    

    Easily fixed by changing the member declarations this:

        command_function_t cmd_{nullptr};
        typename invoke_table_t::type vtable_{nullptr};
    
    1. The use of the variable name allocator in various places triggers a shadow warning, due to the base class in libstdc++ also using it. (note: this is a gcc warning and was built with gcc, not clang)
    declaration of 'allocator' shadows a member of ... [-Werror=shadow]
    include/c++/7/bits/allocator.h:109:5: note: shadowed declaration is here
    
    1. The enum class opcode enumerations use doxygen-like comments that don't follow doxygen correctly, triggering a documentation warning.
    not a Doxygen trailing comment [-Werror,-Wdocumentation]
         op_move,         //< Move the object and set the vtable
                          ^~~
                          ///<
    

    Changing them to this fixes it:

    enum class opcode
    {
        op_move,         ///< Move the object and set the vtable
        op_copy,         ///< Copy the object and set the vtable
        op_destroy,      ///< Destroy the object and reset the vtable
        op_weak_destroy, ///< Destroy the object without resetting the vtable
        op_fetch_empty,  ///< Stores true or false into the to storage
                         ///< to indicate emptiness
    };
    

    Steps to Reproduce

    Build using clang with -Weverything or the specific warnings described earlier, except for (2) which was found using gcc.

    This was built simply as a copied header - i.e., not using the CMake settings in this project. (built for C++17)

    Your Environment

    • OS: Linux
    • Compiler and version: clang version 5.0.0
    • Standard library (if non default): gcc's libstdc++ (from gcc version 7.3.1)
    minor 
    opened by hadrielk 1
Releases(4.2.2)
  • 4.2.2(Oct 26, 2022)

  • 4.2.0(Jun 16, 2021)

  • 4.1.0(Apr 2, 2020)

    • Fix reference types in the return type #35
    • Add a workaround for a MSVC 16.3.1 compiler regression #29
    • Propagate the empty state correctly into the erasure from function like types #27
    • Fix an issue that owning unique functions were accidentally copyable #23
    • Fix a typo in the function property #20
    • And more minor improvements and code cleanups
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Jan 4, 2019)

    • Improved CMake packaging it is now possible to:
      • Install function2 properly
      • Include a function2 subdirectory as subproject
    • The minimum CMake version was raised to 3.11 because of issues with imported interface targets on lower versions.
    • Interface breaking change: The capacity is now an integral_type like type rather than specifying the size directly, this makes it possible to also specify the alignment and it works better with capacities that shall hold a forward declared object which is defined later.
    struct my_capacity {
      static constexpr std::size_t capacity = sizeof(my_type);
      static constexpr std::size_t alignment = alignof(my_type);
    };
    
    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Aug 18, 2018)

    • [#16] Readme Wording
    • [#15] Support and propagate noexcept-qualified function types
    • [#14] Compilation error of fu2::unique_function having a capture
    • [#13] Constructing function_view from fu2::function
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Apr 15, 2018)

    • [a2b8cb0b2] Introduce the non owning function_view
    • [4a3ff153af] Improvements to the size of the whole wrapper object
    • [387f4938c] The object is now guaranteed to be allocated inplace if it fits into the internal buffer
    • Many minor improvements
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Apr 4, 2018)

  • 2.2.0(Oct 1, 2017)

  • 2.0.0(Sep 21, 2017)

    This is the second official release of function2

    • The library was rewritten and requires C++14 support now ,
    • function2 supports multiple signatures now
    Source code(tar.gz)
    Source code(zip)
  • v1.0(Dec 6, 2016)

Owner
Denis Blank
⭐️ Compiler and C++ metaprogramming enthusiast
Denis Blank
A standard conforming C++20 implementation of std::optional.

A standard conforming C++20 implementation of std::optional.

null 31 Aug 24, 2022
C++11/14/17 std::expected with functional-style extensions

expected Single header implementation of std::expected with functional-style extensions. Clang + GCC: MSVC: Available on Vcpkg and Conan. std::expecte

Sy Brand 913 Nov 24, 2022
A collection of std-like single-header C++ libraries

itlib: iboB's Template Libraries A collection of small single-header C++ libraries similar to or extending the C++ standard library. See below for a l

Borislav Stanimirov 96 Nov 7, 2022
Range library for C++14/17/20, basis for C++20's std::ranges

range-v3 Range library for C++14/17/20. This code was the basis of a formal proposal to add range support to the C++ standard library. That proposal e

Eric Niebler 3.6k Nov 29, 2022
Monadic interface for std::optional

optional Simple monadic interface for std::optional Installation Just copy and include optional.h header in your project Usage All operations are in b

null 8 Apr 15, 2022
Allows a programmer to print table-like outputs over std::ostream.

tableprinter Allows a programmer to print table-like outputs over std::ostream. It is a header only library. No other dependency than STL. Provides re

null 24 Jul 7, 2022
This project is pretty straightforward, you have to recode printf. You will learn what is and how to implement variadic functions. Once you validate it, you will reuse this function in your future projects.

100/100 Introduction to ft_printf This is the third project in the 1337 Curriculum #42network . This project is pretty straight forward, recode the pr

Zakaria Yacoubi 4 May 27, 2022
Recode the printf function. This project is of moderate difficulty. It will enable you to discover variadic functions in C.

100/100 ?? Introduction to ft_printf This is the third project in the 42 Cadet Curriculum. This project is pretty straight forward, recode the printf

Paulo Rafael Ramalho 0 Apr 5, 2022
FT_PRINTF is a 42 project that will allow me to remake the printf function (included in ) to be able to reuse it in my next projects.

FT_PRINTF FT_PRINTF is a 42 project that will allow me to remake the printf function (included in <stdio.h>) to be able to reuse it in my next project

Mhamed Ajjig 4 Nov 15, 2022
This project is a copy of the original printf function of C langage.

ft_printf This project is a copy of the original printf function of C langage. Ft_printf (42cursus) 2021-2022 Actual Status : finished. Result : 100%

NABIL ATTIA 2 Dec 11, 2021
expected lite - Expected objects in C++11 and later in a single-file header-only library

expected lite: expected objects for C++11 and later expected lite is a single-file header-only library for objects that either represent a valid value

Martin Moene 240 Nov 22, 2022
gsl-lite – A single-file header-only version of ISO C++ Guidelines Support Library (GSL) for C++98, C++11, and later

gsl-lite: Guidelines Support Library for C++98, C++11 up metadata build packages try online gsl-lite is an implementation of the C++ Core Guidelines S

gsl-lite 765 Nov 28, 2022
optional lite - A C++17-like optional, a nullable object for C++98, C++11 and later in a single-file header-only library

optional lite: A single-file header-only version of a C++17-like optional, a nullable object for C++98, C++11 and later Contents Example usage In a nu

Martin Moene 358 Nov 26, 2022
span lite - A C++20-like span for C++98, C++11 and later in a single-file header-only library

span lite: A single-file header-only version of a C++20-like span for C++98, C++11 and later Contents Example usage In a nutshell License Dependencies

Martin Moene 415 Nov 22, 2022
string_view lite - A C++17-like string_view for C++98, C++11 and later in a single-file header-only library

string_view lite: A single-file header-only version of a C++17-like string_view for C++98, C++11 and later Contents Example usage In a nutshell Licens

Martin Moene 347 Nov 30, 2022
variant lite - A C++17-like variant, a type-safe union for C++98, C++11 and later in a single-file header-only library

variant lite: A single-file header-only version of a C++17-like variant, a type-safe union for C++98, C++11 and later Contents Example usage In a nuts

Martin Moene 221 Nov 26, 2022
gsl-lite – A single-file header-only version of ISO C++ Guidelines Support Library (GSL) for C++98, C++11, and later

gsl-lite: Guidelines Support Library for C++98, C++11 up metadata build packages try online gsl-lite is an implementation of the C++ Core Guidelines S

gsl-lite 765 Nov 28, 2022
Bsl - Rust 2018 and C++20, "constexpr everything", AUTOSAR compliant header-only library intended to support the development of critical systems applications

Description The Bareflank Support Library (BSL) is a Rust 2018 and C++20, "constexpr everything", AUTOSAR compliant header-only library intended to su

Bareflank 74 Oct 15, 2022
Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags.

Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags. Quick start #include <bitflags/bitf

Marin Peko 76 Nov 22, 2022