| Server IP : 217.160.0.135 / Your IP : 216.73.217.85 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 : /usr/lib/python3/dist-packages/pythran/pythonic/types/ |
Upload File : |
#ifndef PYTHONIC_TYPES_VARIANT_FUNCTOR_HPP
#define PYTHONIC_TYPES_VARIANT_FUNCTOR_HPP
#include "pythonic/include/types/variant_functor.hpp"
#include "pythonic/utils/meta.hpp"
#include <utility>
#include <cassert>
PYTHONIC_NS_BEGIN
namespace types
{
namespace details
{
template <class Type>
variant_functor_impl<Type>::variant_functor_impl(char mem[], Type const &t)
: fun(new (mem) Type(t))
{
}
template <class Type>
template <class OtherType>
variant_functor_impl<Type>::variant_functor_impl(char mem[],
OtherType const &t)
: fun(nullptr)
{
}
template <class Type>
variant_functor_impl<Type>::variant_functor_impl(
char mem[], variant_functor_impl<Type> const &t)
: fun(t.fun ? new (mem) Type(*t.fun) : nullptr)
{
}
template <class Type>
template <class... OtherTypes>
variant_functor_impl<Type>::variant_functor_impl(
char mem[], variant_functor_impl<Type, OtherTypes...> const &t)
: variant_functor_impl(mem, t.head)
{
}
template <class Type>
template <class OtherType, class... OtherTypes>
variant_functor_impl<Type>::variant_functor_impl(
char mem[], variant_functor_impl<OtherType, OtherTypes...> const &t)
: variant_functor_impl(mem, t.tail)
{
}
template <class Type>
void
variant_functor_impl<Type>::assign(char mem[],
variant_functor_impl<Type> const &other)
{
if (fun != nullptr)
fun->~Type();
if (other.fun)
fun = new (mem) Type(*other.fun);
}
template <class Type>
void variant_functor_impl<Type>::assign(char mem[],
variant_functor<Type> const &other)
{
assign(mem, static_cast<variant_functor_impl<Type> const &>(other));
}
template <class Type>
template <class OT0, class OT1, class... OtherTypes>
void variant_functor_impl<Type>::assign(
char mem[], variant_functor_impl<OT0, OT1, OtherTypes...> const &other)
{
assign(mem, other.head);
assign(mem, other.tail);
}
template <class Type>
template <class OT0, class OT1, class... OtherTypes>
void variant_functor_impl<Type>::assign(
char mem[], variant_functor<OT0, OT1, OtherTypes...> const &other)
{
assign(mem,
static_cast<variant_functor_impl<OT0, OT1, OtherTypes...> const &>(
other));
}
template <class Type>
template <class OtherType>
void variant_functor_impl<Type>::assign(
char mem[], variant_functor_impl<OtherType> const &other)
{
}
template <class Type>
template <class OtherType>
void
variant_functor_impl<Type>::assign(char mem[],
variant_functor<OtherType> const &other)
{
}
template <class Type>
void variant_functor_impl<Type>::assign(char mem[], Type const &other)
{
if (fun != nullptr)
fun->~Type();
fun = new (mem) Type(other);
}
template <class Type>
variant_functor_impl<Type>::~variant_functor_impl<Type>()
{
if (fun != nullptr)
fun->~Type();
}
template <class Type>
template <class OtherType>
void variant_functor_impl<Type>::assign(char mem[], OtherType const &other)
{
}
template <class Type>
template <class... Args>
auto variant_functor_impl<Type>::operator()(Args &&... args)
-> decltype(std::declval<Type>()(std::forward<Args>(args)...))
{
assert(fun && "handler defined");
return (*fun)(std::forward<Args>(args)...);
}
template <class Type>
template <class... Args>
auto variant_functor_impl<Type>::operator()(Args &&... args) const
-> decltype(std::declval<Type>()(std::forward<Args>(args)...))
{
assert(fun && "handler defined");
return (*fun)(std::forward<Args>(args)...);
}
template <class Type, class... Types>
template <class... OtherTypes>
variant_functor_impl<Type, Types...>::variant_functor_impl(
char mem[], OtherTypes const &... t)
: head(mem, t...), tail(mem, t...)
{
}
template <class Type, class... Types>
template <class... OtherTypes>
variant_functor_impl<Type, Types...>::variant_functor_impl(
char mem[], variant_functor_impl<OtherTypes...> const &t)
: head(mem, t), tail(mem, t)
{
}
template <class Type, class... Types>
void variant_functor_impl<Type, Types...>::assign(
char mem[], variant_functor_impl<Type, Types...> const &other)
{
head.assign(mem, other);
tail.assign(mem, other);
}
template <class Type, class... Types>
template <class OtherType>
void variant_functor_impl<Type, Types...>::assign(char mem[],
OtherType const &other)
{
head.assign(mem, other);
tail.assign(mem, other);
}
template <class Type, class... Types>
template <class... Args>
auto variant_functor_impl<Type, Types...>::operator()(Args &&... args) ->
typename __combined<decltype(std::declval<Type>()(args...)),
decltype(std::declval<Types>()(args...))...>::type
{
if (head.fun)
return head(args...);
else
return tail(args...);
}
template <class Type, class... Types>
template <class... Args>
auto variant_functor_impl<Type, Types...>::operator()(Args &&... args) const
->
typename __combined<decltype(std::declval<Type>()(args...)),
decltype(std::declval<Types>()(args...))...>::type
{
if (head.fun)
return head(args...);
else
return tail(args...);
}
}
template <class... Types>
variant_functor<Types...>::variant_functor(variant_functor const &other)
: details::variant_functor_impl<Types...>(
mem,
static_cast<details::variant_functor_impl<Types...> const &>(other))
{
}
template <class... Types>
variant_functor<Types...> &variant_functor<Types...>::
operator=(variant_functor<Types...> const &other)
{
details::variant_functor_impl<Types...>::assign(mem, other);
return *this;
}
template <class... Types>
template <class... OtherTypes>
variant_functor<Types...> &variant_functor<Types...>::
operator=(variant_functor<OtherTypes...> const &other)
{
details::variant_functor_impl<Types...>::assign(mem, other);
return *this;
}
template <class... Types>
template <class OtherType>
variant_functor<Types...> &variant_functor<Types...>::
operator=(OtherType const &other)
{
static_assert(
utils::any_of<std::is_same<OtherType, Types>::value...>::value,
"consistent assign");
details::variant_functor_impl<Types...>::assign(mem, other);
return *this;
}
template <class... Types>
template <class... OtherTypes>
variant_functor<Types...>::variant_functor(OtherTypes const &... t)
: details::variant_functor_impl<Types...>(mem, t...)
{
}
template <class... Types>
template <class... OtherTypes>
variant_functor<Types...>::variant_functor(
variant_functor<OtherTypes...> const &t)
: details::variant_functor_impl<Types...>(
mem,
static_cast<details::variant_functor_impl<OtherTypes...> const &>(
t))
{
}
}
PYTHONIC_NS_END
#endif