///////////////////////////////////////////////////////////////////////////// // Copyright (c) Electronic Arts Inc. All rights reserved. ///////////////////////////////////////////////////////////////////////////// #ifndef EASTL_FIXED_FUNCTION_H #define EASTL_FIXED_FUNCTION_H #if defined(EA_PRAGMA_ONCE_SUPPORTED) #pragma once #endif #include namespace eastl { template class fixed_function; namespace internal { template struct is_fixed_function : public eastl::false_type {}; template struct is_fixed_function> : public eastl::true_type {}; template EA_CONSTEXPR bool is_fixed_function_v = is_fixed_function::value; } #define EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(TYPE) \ static_assert(sizeof(TYPE) <= sizeof(typename Base::FunctorStorageType), \ "fixed_function local buffer is not large enough to hold the callable object.") #define EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES) \ static_assert(SIZE_IN_BYTES >= NEW_SIZE_IN_BYTES, \ "fixed_function local buffer is not large enough to hold the new fixed_function type.") template using EASTL_DISABLE_OVERLOAD_IF_FIXED_FUNCTION = eastl::disable_if_t>>; // fixed_function // template class fixed_function : public internal::function_detail { using Base = internal::function_detail; public: using typename Base::result_type; fixed_function() EA_NOEXCEPT = default; fixed_function(std::nullptr_t p) EA_NOEXCEPT : Base(p) { } fixed_function(const fixed_function& other) : Base(other) { } fixed_function(fixed_function&& other) : Base(eastl::move(other)) { } template > fixed_function(Functor functor) : Base(eastl::move(functor)) { EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(Functor); } template fixed_function(const fixed_function& other) : Base(other) { EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES); } template fixed_function(fixed_function&& other) : Base(eastl::move(other)) { EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES); } ~fixed_function() EA_NOEXCEPT = default; fixed_function& operator=(const fixed_function& other) { Base::operator=(other); return *this; } fixed_function& operator=(fixed_function&& other) { Base::operator=(eastl::move(other)); return *this; } fixed_function& operator=(std::nullptr_t p) EA_NOEXCEPT { Base::operator=(p); return *this; } template fixed_function& operator=(const fixed_function& other) { EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES); Base::operator=(other); return *this; } template fixed_function& operator=(fixed_function&& other) { EASTL_INTERNAL_FIXED_FUNCTION_NEW_SIZE_STATIC_ASSERT(NEW_SIZE_IN_BYTES); Base::operator=(eastl::move(other)); return *this; } template > fixed_function& operator=(Functor&& functor) { EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(eastl::decay_t); Base::operator=(eastl::forward(functor)); return *this; } template fixed_function& operator=(eastl::reference_wrapper f) EA_NOEXCEPT { EASTL_INTERNAL_FIXED_FUNCTION_STATIC_ASSERT(eastl::reference_wrapper); Base::operator=(f); return *this; } void swap(fixed_function& other) EA_NOEXCEPT { Base::swap(other); } explicit operator bool() const EA_NOEXCEPT { return Base::operator bool(); } R operator ()(Args... args) const { return Base::operator ()(eastl::forward(args)...); } #if EASTL_RTTI_ENABLED const std::type_info& target_type() const EA_NOEXCEPT { return Base::target_type(); } template Functor* target() EA_NOEXCEPT { return Base::target(); } template const Functor* target() const EA_NOEXCEPT { return Base::target(); } #endif }; template bool operator==(const fixed_function& f, std::nullptr_t) EA_NOEXCEPT { return !f; } template bool operator==(std::nullptr_t, const fixed_function& f) EA_NOEXCEPT { return !f; } template bool operator!=(const fixed_function& f, std::nullptr_t) EA_NOEXCEPT { return !!f; } template bool operator!=(std::nullptr_t, const fixed_function& f) EA_NOEXCEPT { return !!f; } template void swap(fixed_function& lhs, fixed_function& rhs) { lhs.swap(rhs); } } // namespace eastl #endif // EASTL_FIXED_FUNCTION_H