| Server IP : 217.160.0.135 / Your IP : 216.73.216.115 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /lib/python3/dist-packages/pythran/pythonic/include/types/ |
Upload File : |
#ifndef PYTHONIC_INCLUDE_TYPES_VARIANT_FUNCTOR_HPP
#define PYTHONIC_INCLUDE_TYPES_VARIANT_FUNCTOR_HPP
#include "pythonic/include/utils/meta.hpp"
#include "pythonic/include/types/combined.hpp"
#include <utility>
PYTHONIC_NS_BEGIN
namespace types
{
/* Variant functor is a generic wrapper for functor object, for which we
*don't know a priori the common signature,
* because of of the variadic operator().
*
* The trick is to allocate a piece of memory large enough to hold any of
*the functor, then maintain, for each functor type, a pointer to that type.
* There can be only one pointer for each variadic set to a non null value
*(based on the preallocated memory buffer).
*
* When calling the functor operator(), the code iterates (linearly) on each
*pointer && call the operator() of this pointer.
*/
template <class... Types>
struct variant_functor;
namespace details
{
template <class... Types>
struct variant_functor_impl;
template <class Type>
struct variant_functor_impl<Type> {
Type *fun = nullptr;
variant_functor_impl() = default;
variant_functor_impl(variant_functor_impl const &) = delete;
~variant_functor_impl();
variant_functor_impl(char mem[], Type const &t);
variant_functor_impl(char mem[], variant_functor_impl<Type> const &t);
template <class... OtherTypes>
variant_functor_impl(char mem[],
variant_functor_impl<Type, OtherTypes...> const &t);
template <class OtherType, class... OtherTypes>
variant_functor_impl(
char mem[], variant_functor_impl<OtherType, OtherTypes...> const &t);
template <class OtherType>
variant_functor_impl(char mem[], OtherType const &t);
variant_functor_impl &operator=(variant_functor_impl const &) = delete;
void assign(char mem[], variant_functor_impl const &);
void assign(char mem[], variant_functor<Type> const &);
void assign(char mem[], Type const &);
template <class OtherType>
void assign(char mem[], OtherType const &);
template <class OT0, class OT1, class... OtherTypes>
void assign(char mem[],
variant_functor_impl<OT0, OT1, OtherTypes...> const &);
template <class OT0, class OT1, class... OtherTypes>
void assign(char mem[], variant_functor<OT0, OT1, OtherTypes...> const &);
template <class OtherType>
void assign(char mem[], variant_functor_impl<OtherType> const &);
template <class OtherType>
void assign(char mem[], variant_functor<OtherType> const &);
template <class... Args>
auto operator()(Args &&... args)
-> decltype(std::declval<Type>()(std::forward<Args>(args)...));
template <class... Args>
auto operator()(Args &&... args) const
-> decltype(std::declval<Type>()(std::forward<Args>(args)...));
};
template <class Type, class... Types>
struct variant_functor_impl<Type, Types...> {
variant_functor_impl<Type> head;
variant_functor_impl<Types...> tail;
variant_functor_impl() = default;
variant_functor_impl(variant_functor_impl const &) = delete;
template <class... OtherTypes>
variant_functor_impl(char mem[], OtherTypes const &... t);
template <class... OtherTypes>
variant_functor_impl(char mem[],
variant_functor_impl<OtherTypes...> const &t);
variant_functor_impl &operator=(variant_functor_impl const &) = delete;
void assign(char mem[], variant_functor_impl const &);
template <class OtherType>
void assign(char mem[], OtherType const &);
template <class... Args>
auto operator()(Args &&... args) -> typename __combined<
decltype(std::declval<Type>()(args...)),
decltype(std::declval<Types>()(args...))...>::type;
template <class... Args>
auto operator()(Args &&... args) const -> typename __combined<
decltype(std::declval<Type>()(args...)),
decltype(std::declval<Types>()(args...))...>::type;
};
}
template <class... Types>
struct variant_functor : details::variant_functor_impl<Types...> {
using callable = void;
// memory used to initialize the actual functor
// default construction cannot be used because generator are not
// default-constructible
char mem[utils::max_element<sizeof(Types)...>::value];
variant_functor() = default;
variant_functor(variant_functor const &);
variant_functor &operator=(variant_functor const &);
template <class OtherType>
variant_functor &operator=(OtherType const &);
template <class... OtherTypes>
variant_functor &operator=(variant_functor<OtherTypes...> const &);
template <class... OtherTypes>
variant_functor(OtherTypes const &... t);
template <class... OtherTypes>
variant_functor(variant_functor<OtherTypes...> const &t);
};
}
PYTHONIC_NS_END
#endif