Skip to content

Commit

Permalink
iox-eclipse-iceoryx#391 fixed function_ref construction from function…
Browse files Browse the repository at this point in the history
… pointer

Signed-off-by: Matthias Killat <matthias.killat@apex.ai>
  • Loading branch information
MatthiasKillat committed Dec 14, 2020
1 parent b8e736d commit a1ec536
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
13 changes: 10 additions & 3 deletions iceoryx_utils/include/iceoryx_utils/cxx/function_ref.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -71,10 +71,17 @@ class function_ref<ReturnType(ArgTypes...)>
/// @brief Creates a function_ref with a callable whose lifetime has to be longer than function_ref
/// @param[in] callable that is not a function_ref
template <typename CallableType,
typename = std::enable_if_t<not_same<CallableType, function_ref>::value>,
typename = std::enable_if_t<is_invocable<CallableType, ArgTypes...>::value>>
typename = std::enable_if_t<!is_function_pointer<CallableType>::value
&& not_same<CallableType, function_ref>::value
&& is_invocable<CallableType, ArgTypes...>::value>>
function_ref(CallableType&& callable) noexcept;

/// @brief Creates a function_ref from a function pointer
/// @param[in] function function pointer to function we want to reference
/// @note this overload is needed, the general implementation is
/// using std::adressof and will not work properly for function pointers
function_ref(ReturnType (*function)(ArgTypes...));

function_ref(function_ref&& rhs) noexcept;

function_ref& operator=(function_ref&& rhs) noexcept;
Expand Down
16 changes: 15 additions & 1 deletion iceoryx_utils/include/iceoryx_utils/cxx/type_traits.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -63,6 +63,20 @@ struct has_signature<Callable,
{
};

///
/// @brief Check whteher T is a function pointer with arbitrary signature
///
template <typename T>
struct is_function_pointer
{
static constexpr bool value = false;
};
template <typename ReturnType, typename... ArgTypes>
struct is_function_pointer<ReturnType (*)(ArgTypes...)>
{
static constexpr bool value = true;
};

///
/// @brief Negation of is_same
///
Expand Down
19 changes: 17 additions & 2 deletions iceoryx_utils/include/iceoryx_utils/internal/cxx/function_ref.inl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,7 @@ inline function_ref<ReturnType(ArgTypes...)>::function_ref() noexcept
}

template <class ReturnType, class... ArgTypes>
template <typename CallableType, typename, typename>
template <typename CallableType, typename>
inline function_ref<ReturnType(ArgTypes...)>::function_ref(CallableType&& callable) noexcept
: m_pointerToCallable(reinterpret_cast<void*>(std::addressof(callable)))
, m_functionPointer([](void* target, ArgTypes... args) -> ReturnType {
Expand All @@ -34,6 +34,21 @@ inline function_ref<ReturnType(ArgTypes...)>::function_ref(CallableType&& callab
{
}

template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>::function_ref(ReturnType (*function)(ArgTypes...))
{
///@note the cast is not portable but works and is legal on POSIX
///@todo we should consider storing the target in a portable way (e.g. a union)
m_pointerToCallable = reinterpret_cast<void*>(function);

///@note the lambda does not capture and is convertible to a function pointer
/// as required by the C++ standard
m_functionPointer = [](void* target, ArgTypes... args) -> ReturnType {
auto f = reinterpret_cast<ReturnType (*)(ArgTypes...)>(target);
return f(std::forward<ArgTypes>(args)...);
};
}

template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>::function_ref(function_ref&& rhs) noexcept
{
Expand Down

0 comments on commit a1ec536

Please sign in to comment.