Repositories / jai.git
jai.git
Clone (read-only): git clone http://git.guha-anderson.com/git/jai.git
@@ -6,7 +6,7 @@ AM_CXXFLAGS = $(MOUNT_CFLAGS) $(LIBACL_CFLAGS) jai_SOURCES = complete.cc cred.cc default_conf.cc fs.cc jai.cc \ options.cc argtype.h config.h cred.h defer.h err.h fs.h jai.h \ -options.h +move_only_function.h options.h jai_LDADD = $(MOUNT_LIBS) $(LIBACL_LIBS) man1_MANS = jai.1
@@ -12,15 +12,9 @@ AC_PROG_CXX # Require C++23 CXXFLAGS="$CXXFLAGS $CXXLANG" AC_LANG_PUSH([C++]) -AC_MSG_CHECKING(for working C++23 features) +AC_MSG_CHECKING(for a working C++23 library) AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([ -#include <functional> -#include <print> - ], [ -std::move_only_function<void()> f = []{}; -f(); - ])], + [AC_LANG_PROGRAM([#include <print>], [])], [AC_MSG_RESULT(yes)], [AC_MSG_ERROR([a C++23 compiler is required])]) AC_LANG_POP([C++])
@@ -3,6 +3,7 @@ #pragma once #include "argtype.h" +#include "move_only_function.h" #include <concepts> #include <functional> @@ -78,5 +79,5 @@ struct NullaryInvoker { }; } // namespace detail // Deferred cleanup action -using Defer = RaiiHelper<detail::NullaryInvoker{}, - std::move_only_function<void()>, nullptr>; +using Defer = + RaiiHelper<detail::NullaryInvoker{}, move_only_function<void()>, nullptr>;
@@ -0,0 +1,57 @@ +// -*-C++-*- + +#pragma once + +#include <functional> + +#if __cpp_lib_move_only_function >= 202110L + +using std::move_only_function; + +#else // std::move_only_function unimplemented + +#include <memory> + +template<typename F> struct move_only_function; + +template<typename R, typename... Args, bool NE> +class move_only_function<R(Args...) noexcept(NE)> { +public: + struct Invoker { + virtual ~Invoker() = default; + virtual R operator()(Args... args) noexcept(NE) = 0; + }; + template<typename F> struct Impl : Invoker { + F f_; + // Impl(F f) : f_(std::move(f)) {} + template<typename RF> Impl(RF &&f) : f_(std::forward<RF>(f)) {} + R operator()(Args... args) noexcept(NE) override + { + return std::invoke(f_, std::forward<Args>(args)...); + } + }; + template<typename F> Impl(F &&) -> Impl<std::decay_t<F>>; + + std::unique_ptr<Invoker> inv_; + +public: + move_only_function() noexcept = default; + move_only_function(std::nullptr_t) noexcept {}; + move_only_function(move_only_function &&) noexcept = default; + + template<std::invocable<Args...> F> + move_only_function(F f) : inv_(new Impl{std::move(f)}) + {} + + move_only_function &operator=(move_only_function &&) noexcept = default; + + R operator()(Args ...args) noexcept(NE) + { + return (*inv_)(std::forward<Args>(args)...); + } + + explicit operator bool() noexcept { return inv_; } + bool operator==(std::nullptr_t) noexcept { return !inv_; } +}; + +#endif // std::move_only_function unimplemented
@@ -1,6 +1,8 @@ #include "options.h" +#include <algorithm> + void Options::parse_file(std::string_view text, std::string_view errpath) {