-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplify overload system to get meaningful errors and compile faster
This is the 1st PR toward this goal. More to come.
- Loading branch information
Showing
17 changed files
with
878 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//================================================================================================== | ||
/* | ||
EVE - Expressive Vector Engine | ||
Copyright : EVE Project Contributors | ||
SPDX-License-Identifier: BSL-1.0 | ||
*/ | ||
//================================================================================================== | ||
#pragma once | ||
|
||
#include <eve/detail/raberu.hpp> | ||
|
||
namespace eve | ||
{ | ||
template<typename T> | ||
concept callable_options = rbr::concepts::settings<T>; | ||
|
||
template<typename T> | ||
concept callable_option = rbr::concepts::option<T>; | ||
|
||
template<typename Option, auto Keyword> | ||
concept exactly = rbr::concepts::exactly<Option,Keyword>; | ||
|
||
template<typename Option, auto... Keyword> | ||
concept any_options_from = callable_option<Option> && (exactly<Option,Keyword> || ...); | ||
|
||
/// Checks if the type associated to a given Keyword in a Option pack is equal to Type | ||
template<auto Keyword, typename Opts,typename Type> | ||
concept match_option = std::same_as<Type, rbr::result::fetch_t<Keyword,Opts>>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//====================================================================================================================== | ||
/* | ||
EVE - Expressive Vector Engine | ||
Copyright : EVE Project Contributors | ||
SPDX-License-Identifier: BSL-1.0 | ||
*/ | ||
//====================================================================================================================== | ||
#pragma once | ||
|
||
#include <eve/traits/overload/protocol.hpp> | ||
#include <eve/traits/overload/supports.hpp> | ||
#include <eve/traits/overload/default_behaviors.hpp> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
//====================================================================================================================== | ||
/* | ||
EVE - Expressive Vector Engine | ||
Copyright : EVE Project Contributors | ||
SPDX-License-Identifier: BSL-1.0 | ||
*/ | ||
//====================================================================================================================== | ||
#pragma once | ||
|
||
#include <eve/concept/value.hpp> | ||
#include <eve/detail/skeleton.hpp> | ||
#include <eve/detail/function/conditional.hpp> | ||
|
||
namespace eve | ||
{ | ||
namespace detail | ||
{ | ||
inline constexpr struct { EVE_FORCEINLINE auto operator()(auto, auto x) const { return x; } } return_2nd = {}; | ||
} | ||
|
||
//==================================================================================================================== | ||
|
||
//==================================================================================================================== | ||
template< template<typename> class Func | ||
, typename OptionsValues | ||
, typename... Options | ||
> | ||
struct callable : decorated_with<OptionsValues, Options...> | ||
{ | ||
using base = decorated_with<OptionsValues, Options...>; | ||
|
||
template<typename T> | ||
constexpr auto operator[](T t) const | ||
requires( requires(base const& b) { b[t];} ) | ||
{ | ||
auto new_traits = base::operator[](t); | ||
return Func<decltype(new_traits)>{new_traits}; | ||
} | ||
|
||
template<typename T> void operator[](T t) const =delete; | ||
|
||
template<typename... Args> | ||
constexpr auto behavior(auto arch, Args&&... args) const | ||
{ | ||
return Func<OptionsValues>::deferred_call(arch, EVE_FWD(args)...); | ||
} | ||
|
||
protected: | ||
constexpr Func<OptionsValues> const& derived() const { return static_cast<Func<OptionsValues>>(*this); } | ||
}; | ||
|
||
//==================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @struct constant_callable | ||
//! @brief CRTP base class giving an EVE's @callable the constant function semantic | ||
//! | ||
//! **Defined in Header** | ||
//! | ||
//! @code | ||
//! #include <eve/module/core.hpp> | ||
//! @endcode | ||
//! | ||
//! Constants functions in EVE are built using a very common pattern. Inheriting from eve::constant simplifies the | ||
//! implementation of such eve::callable by just requiring your eve::callable type to implement a static `value` | ||
//! member function that provides the constant value using two parameters: | ||
//! * an eve::options pack containing potential decorators passed to the constant. | ||
//! * an eve::as instance to specify the output type. | ||
//! | ||
//! Constant functions in EVE also supports masking, which is directly implemented in eve::constant. | ||
//! | ||
//! @note The deferred overload named in the EVE_CALLABLE_OBJECT macro process is still available if an architecture | ||
//! specific implementation of any given constant is required. | ||
//! | ||
//! @tparam Tag Type of current @callable being implemented | ||
//! | ||
//! @groupheader{Example} | ||
//! @godbolt{doc/traits/callable_constant.cpp} | ||
//! @} | ||
//==================================================================================================================== | ||
template< template<typename> class Func | ||
, typename OptionsValues | ||
, typename... Options | ||
> | ||
struct constant_callable : callable<Func, OptionsValues, conditional_option, Options...> | ||
{ | ||
template<typename O, typename T> | ||
constexpr auto behavior(auto arch, O const& opts, as<T> const& target) const | ||
{ | ||
using func_t = Func<OptionsValues>; | ||
if constexpr( requires{ func_t::deferred_call(arch, opts, target); } ) | ||
{ | ||
return func_t::deferred_call(arch, opts, target); | ||
} | ||
else | ||
{ | ||
// Compute the raw constant | ||
auto const constant_value = Func<OptionsValues>::value(target,opts); | ||
|
||
// Apply a mask if any and replace missing values with 0 if no alternative is provided | ||
if constexpr(match_option<condition_key, O, ignore_none_>) return constant_value; | ||
else return detail::mask_op(opts[condition_key], detail::return_2nd, 0, constant_value); | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
//====================================================================================================================== | ||
//! @file | ||
/* | ||
EVE - Expressive Vector Engine | ||
Copyright : EVE Project Contributors | ||
SPDX-License-Identifier: BSL-1.0 | ||
*/ | ||
//====================================================================================================================== | ||
#pragma once | ||
|
||
#include <eve/arch/tags.hpp> | ||
|
||
//====================================================================================================================== | ||
//! @addtogroup simd | ||
//! @{ | ||
//! @defgroup extensions Extensions points | ||
//! @brief Macros, classes and functions designed to extend EVE externally. | ||
//! @} | ||
//====================================================================================================================== | ||
|
||
namespace eve | ||
{ | ||
//==================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @concept callable_object | ||
//! @brief **EVE** callable object | ||
//! | ||
//! **Defined in Header** | ||
//! | ||
//! @code | ||
//! #include <eve/module/core.hpp> | ||
//! @endcode | ||
//! | ||
//! A type `T` satisfies eve::callable_object if and only if it is tagged as such manually. | ||
//! | ||
//! @tparam T T type for the @callable to check | ||
//! @} | ||
//==================================================================================================================== | ||
template<typename T, typename...> | ||
concept callable_object = requires(T const&) { typename T::callable_tag_type; }; | ||
} | ||
|
||
//====================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @def EVE_CALLABLE_OBJECT_FROM | ||
//! @brief Generate the generic function interface for any EVE-compatible @callable | ||
//! | ||
//! **Defined in Header** | ||
//! | ||
//! @code | ||
//! #include <eve/module/core.hpp> | ||
//! @endcode | ||
//! | ||
//! Use inside a @callable definition to generate the required EVE protocol of function's resolution based on type | ||
//! and architecture informations. | ||
//! | ||
//! @param NS Namespace in which specialization of the @callable will be found. This namespace must have been | ||
//! registered via EVE_CALLABLE_NAMESPACE. | ||
//! @param TYPE Current @callable type | ||
//! @param NAME Function identifier for overloads. Calls to `NS::NAME` are supposed to succeed. | ||
//! | ||
//! @see EVE_CALLABLE_OBJECT | ||
//! @see EVE_CALLABLE_NAMESPACE | ||
//! | ||
//! @groupheader{Usage} | ||
//! | ||
//! @ref EVE_CALLABLE_OBJECT_FROM generates the expected code for defining a EVE @callable. EVE @callable are function | ||
//! object which supports decorators and use an external function to specify its implementation. | ||
//! | ||
//! @ref EVE_CALLABLE_OBJECT_FROM relies on its enclosing type to provide at least one declaration of a member function | ||
//! named `call` which represent the expected prototype of the function object, including potential constraints, and | ||
//! its associated return type. @ref EVE_CALLABLE_OBJECT also relies on the existence of an appropriate number of | ||
//! function overloads named `NAME` defined in the `NS` namespace. Those function contains the implementation | ||
//! of the @callable overload for each pre-defined function. | ||
//! | ||
//! @groupheader{Example} | ||
//! | ||
//! @godbolt{doc/traits/callable_object_from.cpp} | ||
//! @} | ||
//====================================================================================================================== | ||
#define EVE_CALLABLE_OBJECT_FROM(NS,TYPE,NAME) \ | ||
template<typename... Args> \ | ||
static EVE_FORCEINLINE auto deferred_call(auto arch, Args&&...args) noexcept \ | ||
-> decltype(NAME(NS::adl_helper, arch, EVE_FWD(args)...)) \ | ||
{ \ | ||
return NAME( NS::adl_helper, arch, EVE_FWD(args)...); \ | ||
} \ | ||
using callable_tag_type = TYPE \ | ||
/**/ | ||
|
||
// THIS MACRO IS DUPLICATED TO ENSURE ERROR MESSAGE QUALITY | ||
//====================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @def EVE_CALLABLE_OBJECT | ||
//! @brief Generate the generic function interface for an actual eve::callable | ||
//! | ||
//! **Defined in Header** | ||
//! | ||
//! @code | ||
//! #include <eve/module/core.hpp> | ||
//! @endcode | ||
//! | ||
//! Use inside a @callable definition to generate the required EVE protocol of function's resolution based on type | ||
//! and architecture informations using overload from the `eve::detail` namespace. | ||
//! | ||
//! @warning @ref EVE_CALLABLE_OBJECT is mostly used for EVE @callable definition. If you want to use EVE's overload | ||
//! facility for your own library, use @ref EVE_CALLABLE_OBJECT_FROM. | ||
//! | ||
//! @param TYPE Current @callable type | ||
//! @param NAME Function identifier for overloads. Calls to `eve::detail::NAME` are supposed to succeed. | ||
//! | ||
//! @groupheader{Usage} | ||
//! | ||
//! @ref EVE_CALLABLE_OBJECT generates the expected code for defining a EVE @callable. EVE @callable are function | ||
//! object which supports decorators and use an external function to specify its implementation. | ||
//! | ||
//! @ref EVE_CALLABLE_OBJECT relies on its enclosing type to provide at least one declaration of a member function | ||
//! named `call` which represent the expected prototype of the function object, including potential constraints, and | ||
//! its associated return type. @ref EVE_CALLABLE_OBJECT also relies on the existence of an appropriate number of | ||
//! function overloads named `NAME` defined in the eve::detail namespace. Those function contains the implementation | ||
//! of the @callable overload for each pre-defined function. | ||
//! | ||
//! @groupheader{Example} | ||
//! | ||
//! @godbolt{doc/traits/callable_object.cpp} | ||
//! @} | ||
//====================================================================================================================== | ||
#define EVE_CALLABLE_OBJECT(TYPE,NAME) \ | ||
template<typename... Args> \ | ||
static EVE_FORCEINLINE auto deferred_call(auto arch, Args&&...args) noexcept \ | ||
-> decltype(NAME(eve::detail::adl_helper, arch, EVE_FWD(args)...)) \ | ||
{ \ | ||
return NAME(eve::detail::adl_helper, arch, EVE_FWD(args)...); \ | ||
} \ | ||
using callable_tag_type = TYPE \ | ||
/**/ | ||
|
||
//====================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @def EVE_DISPATCH_CALL | ||
//! @brief Generate the proper call to current EVE's @callable implementation | ||
//! @} | ||
//====================================================================================================================== | ||
#define EVE_DISPATCH_CALL(...) \ | ||
this->behavior(eve::current_api, this->options(), __VA_ARGS__) \ | ||
/**/ | ||
|
||
//====================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @def EVE_CALLABLE_NAMESPACE | ||
//! @brief Register a namespace as suitable for containing eve::callable overloads. | ||
//! @} | ||
//====================================================================================================================== | ||
#define EVE_CALLABLE_NAMESPACE() \ | ||
struct adl_helper_t {}; \ | ||
inline constexpr auto adl_helper = adl_helper_t {} \ | ||
/**/ | ||
|
||
//====================================================================================================================== | ||
//! @addtogroup extensions | ||
//! @{ | ||
//! @def EVE_REQUIRES | ||
//! @brief Flag a function to support delayed calls on given architecture | ||
//! @} | ||
//====================================================================================================================== | ||
#define EVE_REQUIRES(ARCH) adl_helper_t const &, ARCH const & | ||
|
||
// Register eve::detail as the deferred namespace by default | ||
namespace eve::detail { EVE_CALLABLE_NAMESPACE(); } |
Oops, something went wrong.