omni/Function.h
File members: omni/Function.h
// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include <functional>
#include "detail/FunctionImpl.h"
#include "../carb/detail/NoexceptType.h"
namespace omni
{
using std::bad_function_call;
template <typename Signature>
class function;
template <typename TReturn, typename... TArgs>
class function<TReturn(TArgs...)> : private ::omni::detail::FunctionData
{
using base_type = ::omni::detail::FunctionData;
using traits = ::omni::detail::FunctionTraits<TReturn(TArgs...)>;
public:
using result_type = typename traits::result_type;
public:
function(std::nullptr_t) noexcept : base_type(nullptr)
{
}
function() noexcept : function(nullptr)
{
}
function(function const& other) = default;
function(function&& other) noexcept = default;
function& operator=(std::nullptr_t) noexcept
{
reset();
return *this;
}
function& operator=(function const& other) = default;
function& operator=(function&& other) noexcept = default;
CARB_DETAIL_PUSH_IGNORE_NOEXCEPT_TYPE()
template <typename F, typename Assigner = ::omni::detail::FunctionAssigner<traits, F>>
function(F&& f) : base_type(Assigner{}, std::forward<F>(f))
{
}
template <typename F, typename Assigner = ::omni::detail::FunctionAssigner<traits, F>>
function& operator=(F&& f)
{
return operator=(function{ std::forward<F>(f) });
}
CARB_DETAIL_POP_IGNORE_NOEXCEPT_TYPE()
~function() noexcept = default;
TReturn operator()(TArgs... args) const
{
if (m_trampoline == nullptr)
::omni::detail::null_function_call();
auto f = reinterpret_cast<TReturn (*)(::omni::detail::FunctionBuffer const*, TArgs...)>(m_trampoline);
return f(&m_buffer, std::forward<TArgs>(args)...);
}
explicit operator bool() const noexcept
{
return bool(m_trampoline);
}
void swap(function& other) noexcept
{
base_type::swap(other);
}
};
template <typename TReturn, typename... TArgs>
bool operator==(function<TReturn(TArgs...)> const& func, std::nullptr_t) noexcept
{
return !func;
}
template <typename TReturn, typename... TArgs>
bool operator==(std::nullptr_t, function<TReturn(TArgs...)> const& func) noexcept
{
return !func;
}
template <typename TReturn, typename... TArgs>
bool operator!=(function<TReturn(TArgs...)> const& func, std::nullptr_t) noexcept
{
return static_cast<bool>(func);
}
template <typename TReturn, typename... TArgs>
bool operator!=(std::nullptr_t, function<TReturn(TArgs...)> const& func) noexcept
{
return static_cast<bool>(func);
}
template <typename TReturn, typename... TArgs>
void swap(function<TReturn(TArgs...)>& a, function<TReturn(TArgs...)>& b) noexcept
{
a.swap(b);
}
} // namespace omni