iceoryx_utils/internal/cxx/function_ref.inl🔗
Namespaces🔗
Name |
---|
iox building block to easily create free function for logging in a library context |
iox::cxx |
Source code🔗
// Copyright (c) 2020 by Robert Bosch GmbH. 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
namespace iox
{
namespace cxx
{
template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>::function_ref() noexcept
: m_pointerToCallable(nullptr)
, m_functionPointer(nullptr)
{
}
template <class ReturnType, class... ArgTypes>
template <typename CallableType, typename, 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 {
return (*reinterpret_cast<typename std::add_pointer<CallableType>::type>(target))(
std::forward<ArgTypes>(args)...);
})
{
}
template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>::function_ref(function_ref&& rhs) noexcept
{
*this = std::move(rhs);
}
template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>&
function_ref<ReturnType(ArgTypes...)>::operator=(function_ref<ReturnType(ArgTypes...)>&& rhs) noexcept
{
if (this != &rhs)
{
m_pointerToCallable = rhs.m_pointerToCallable;
m_functionPointer = rhs.m_functionPointer;
// Make sure no undefined behavior can happen by marking the rhs as invalid
rhs.m_pointerToCallable = nullptr;
rhs.m_functionPointer = nullptr;
}
return *this;
}
template <class ReturnType, class... ArgTypes>
inline ReturnType function_ref<ReturnType(ArgTypes...)>::operator()(ArgTypes... args) const noexcept
{
if (!m_pointerToCallable)
{
// Callable was called without user having assigned one beforehand
std::cerr << "Empty function_ref invoked" << std::endl;
std::terminate();
}
return m_functionPointer(m_pointerToCallable, std::forward<ArgTypes>(args)...);
}
template <class ReturnType, class... ArgTypes>
inline function_ref<ReturnType(ArgTypes...)>::operator bool() const noexcept
{
return m_pointerToCallable != nullptr;
}
template <class ReturnType, class... ArgTypes>
inline void function_ref<ReturnType(ArgTypes...)>::swap(function_ref<ReturnType(ArgTypes...)>& rhs) noexcept
{
std::swap(m_pointerToCallable, rhs.m_pointerToCallable);
std::swap(m_functionPointer, rhs.m_functionPointer);
}
template <class ReturnType, class... ArgTypes>
inline void swap(function_ref<ReturnType(ArgTypes...)>& lhs, function_ref<ReturnType(ArgTypes...)>& rhs) noexcept
{
lhs.swap(rhs);
}
} // namespace cxx
} // namespace iox
Updated on 31 May 2022 at 15:29:15 CEST