Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
alabuzhev committed Oct 4, 2022
1 parent fe911f7 commit a0e924a
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 10 deletions.
2 changes: 1 addition & 1 deletion far/RegExp.cpp
Expand Up @@ -3983,7 +3983,7 @@ TEST_CASE("regex.named_groups")

for (const auto& [k, v]: i.NamedMatch)
{
const auto It = NamedMatch.Matches.find(k);
const auto It = NamedMatch.Matches.find(string_comparer::generic_key{ k });
REQUIRE(It != NamedMatch.Matches.cend());
REQUIRE(It->second == v);
}
Expand Down
56 changes: 56 additions & 0 deletions far/common.tests.cpp
Expand Up @@ -506,6 +506,62 @@ TEST_CASE("from_string")

//----------------------------------------------------------------------------

#include "common/function_ref.hpp"

TEST_CASE("function_ref")
{
{
struct s
{
static int square(int const i) { return i * i; }
};

function_ref const Func = &s::square;
REQUIRE(Func(2) == 4);
}

{
struct square
{
int operator()(int const i) const { return i * i; }
};

square const Square;
function_ref const Func = Square;
REQUIRE(Func(2) == 4);
}

{
const auto square = [](int const i) { return i * i; };

function_ref const Func = square;
REQUIRE(Func(2) == 4);
}

{
const auto square = [&](int const i) { return i * i; };

function_ref const Func = square;
REQUIRE(Func(2) == 4);
}

{
auto square = [&](int const i) mutable { return i * i; };

function_ref const Func = square;
REQUIRE(Func(2) == 4);
}

{
const auto square = [](int const i) mutable { return i * i; };

function_ref const Func = square;
REQUIRE(Func(2) == 4);
}
}

//----------------------------------------------------------------------------

#include "common/function_traits.hpp"

TEST_CASE("function_traits")
Expand Down
28 changes: 25 additions & 3 deletions far/common/function_ref.hpp
Expand Up @@ -33,6 +33,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "preprocessor.hpp"
#include "function_traits.hpp"

#include <functional>

Expand All @@ -48,11 +49,11 @@ class function_ref<return_type(args...)> final
WARNING_PUSH()
WARNING_DISABLE_MSC(4180) // qualifier applied to function type has no meaning; ignored
template<typename callable_type, REQUIRES(!std::is_same_v<std::decay_t<callable_type>, function_ref>)>
function_ref(const callable_type& Callable) noexcept:
m_Ptr(const_cast<void*>(reinterpret_cast<const void*>(&Callable))),
function_ref(callable_type&& Callable) noexcept:
m_Ptr(to_ptr(FWD(Callable))),
m_ErasedFn([](void* Ptr, args... Args) -> return_type
{
return std::invoke(*reinterpret_cast<const callable_type*>(Ptr), FWD(Args)...);
return std::invoke(from_ptr<callable_type>(Ptr), FWD(Args)...);
})
{
}
Expand All @@ -76,10 +77,31 @@ WARNING_POP()
}

private:
template<typename callable_type>
static auto to_ptr(callable_type&& Callable)
{
if constexpr (std::is_pointer_v<callable_type>)
return const_cast<void*>(reinterpret_cast<const void*>(Callable));
else
return const_cast<void*>(reinterpret_cast<const void*>(&Callable));
}

template<typename callable_type>
static auto& from_ptr(void* Ptr)
{
if constexpr (std::is_pointer_v<callable_type>)
return *reinterpret_cast<callable_type>(Ptr);
else
return *reinterpret_cast<std::add_pointer_t<callable_type>>(Ptr);
}

using signature_type = return_type(void*, args...);

void* m_Ptr;
signature_type* m_ErasedFn;
};

template<typename object>
function_ref(object) -> function_ref<typename function_traits<object>::signature_type>;

#endif // FUNCTION_REF_HPP_0B2E3AF4_AB0A_4C89_9FC1_1A92AC2699A4
1 change: 1 addition & 0 deletions far/common/function_traits.hpp
Expand Up @@ -42,6 +42,7 @@ namespace detail
struct function_traits_impl
{
using result_type = result;
using signature_type = result(args...);

static constexpr auto arity = sizeof...(args);

Expand Down
8 changes: 2 additions & 6 deletions far/interf.cpp
Expand Up @@ -1206,9 +1206,7 @@ size_t string_pos_to_visual_pos(string_view Str, size_t const StringPos, size_t
if (SavedState && StringPos > SavedState->StringIndex)
State = *SavedState;

// Lambda capture is essential here, without it the lambda will happily convert itself
// to a temporary function pointer and function_ref will refer to that temporary.
const auto nop_signal = [&](size_t, size_t){};
const auto nop_signal = [](size_t, size_t){};
const auto signal = State.signal? State.signal : nop_signal;

const auto End = std::min(Str.size(), StringPos);
Expand Down Expand Up @@ -1263,9 +1261,7 @@ size_t visual_pos_to_string_pos(string_view Str, size_t const VisualPos, size_t
if (SavedState && VisualPos > SavedState->VisualIndex)
State = *SavedState;

// Lambda capture is essential here, without it the lambda will happily convert itself
// to a temporary function pointer and function_ref will refer to that temporary.
const auto nop_signal = [&](size_t, size_t){};
const auto nop_signal = [](size_t, size_t){};
const auto signal = State.signal? State.signal : nop_signal;

const auto End = Str.size();
Expand Down

0 comments on commit a0e924a

Please sign in to comment.