AUI Framework  master
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
tuples.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13#include <tuple>
   14
   15namespace tuples
   16{
   17    namespace detail
   18    {
   19        namespace functor
   20        {
   21            struct mul {
   22                template<typename A, typename B>
   23                auto operator()(A a, B b)
   24                {
   25                    return a * b;
   26                }
   27            };
   28            struct add {
   29                template<typename A, typename B>
   30                auto operator()(A a, B b)
   31                {
   32                    return a + b;
   33                }
   34            };
   35            struct sub {
   36                template<typename A, typename B>
   37                auto operator()(A a, B b)
   38                {
   39                    return a - b;
   40                }
   41            };
   42            struct div {
   43                template<typename A, typename B>
   44                auto operator()(A a, B b)
   45                {
   46                    return a / b;
   47                }
   48            };
   49        }
   50
   51        template<typename Function, typename Tuple, size_t... I>
   52        void call(Function f, Tuple t, std::index_sequence<I...>)
   53        {
   54            f(std::get<I>(t)...);
   55        }
   56
   57        template<typename Functor, typename Num, typename Tuple, size_t... I>
   58        Tuple do_transform(Functor f, const Tuple& t, Num n, std::index_sequence<I...>)
   59        {
   60            return std::make_tuple(f(std::get<I>(t), n)...);
   61        }
   62        template<typename Functor, typename Tuple, size_t... I>
   63        Tuple do_transform(Functor f, const Tuple& t1, const Tuple& t2, std::index_sequence<I...>)
   64        {
   65            return std::make_tuple(f(std::get<I>(t1), std::get<I>(t2))...);
   66        }
   67    }
   68
   69    template<typename Function, typename Tuple>
   70    void call(Function f, Tuple t)
   71    {
   72        detail::call(f, t, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
   73    }
   74}
   75
   76template<typename Num, typename... Types>
   77std::tuple<Types...> operator+(const std::tuple<Types...>& l, Num n)
   78{
   79    return tuples::detail::do_transform(tuples::detail::functor::add(), l, n,
   80        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
   81}
   82template<typename Num, typename... Types>
   83std::tuple<Types...> operator+(const std::tuple<Types...>& l, const std::tuple<Types...>& r)
   84{
   85    return tuples::detail::do_transform(tuples::detail::functor::add(), l, r,
   86        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
   87}
   88
   89template<typename Num, typename... Types>
   90std::tuple<Types...> operator-(const std::tuple<Types...>& l, Num n)
   91{
   92    return tuples::detail::do_transform(tuples::detail::functor::sub(), l, n,
   93        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
   94}
   95template<typename Num, typename... Types>
   96std::tuple<Types...> operator-(const std::tuple<Types...>& l, const std::tuple<Types...>& r)
   97{
   98    return tuples::detail::do_transform(tuples::detail::functor::sub(), l, r,
   99        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
  100}
  101
  102
  103template<typename Num, typename... Types>
  104std::tuple<Types...> operator/(const std::tuple<Types...>& l, Num n)
  105{
  106    return tuples::detail::do_transform(tuples::detail::functor::div(), l, n,
  107        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
  108}
  109template<typename Num, typename... Types>
  110std::tuple<Types...> operator/(const std::tuple<Types...>& l, const std::tuple<Types...>& r)
  111{
  112    return tuples::detail::do_transform(tuples::detail::functor::div(), l, r,
  113        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
  114}
  115
  116template<typename Num, typename... Types>
  117std::tuple<Types...> operator*(const std::tuple<Types...>& l, Num n)
  118{
  119    return tuples::detail::do_transform(tuples::detail::functor::mul(), l, n,
  120        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
  121}
  122template<typename Num, typename... Types>
  123std::tuple<Types...> operator*(const std::tuple<Types...>& l, const std::tuple<Types...>& r)
  124{
  125    return tuples::detail::do_transform(tuples::detail::functor::mul(), l, r,
  126        std::make_index_sequence<std::tuple_size_v<std::tuple<Types...>>>{});
  127}