Live Cells C++
Reactive Programming for C++
Loading...
Searching...
No Matches
util.hpp
1/*
2 * live_cells_cpp
3 * Copyright (C) 2024 Alexander Gutev <alex.gutev@gmail.com>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you
6 * may not use this file except in compliance with the License. You
7 * may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 */
17
18#ifndef LIVE_CELLS_UTIL_HPP
19#define LIVE_CELLS_UTIL_HPP
20
21#include <tuple>
22#include <utility>
23
24namespace live_cells {
25
26 namespace internal {
27
28 inline std::size_t hash_combine(std::size_t seed) {
29 return seed;
30 }
31
41 template <typename T, typename... Rest>
42 std::size_t hash_combine(std::size_t seed, const T& v, const Rest&... rest)
43 {
44 seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
45 return hash_combine(seed, rest...);
46 }
47
54 template <typename... Ts>
55 struct count_args {
56 };
57
58 template <typename T, typename... Ts>
59 struct count_args<T, Ts...> {
60 static constexpr size_t size = 1 + count_args<Ts...>::size;
61 };
62
63 template <>
64 struct count_args<> {
65 static constexpr size_t size = 0;
66 };
67
74 template <size_t S, typename... Ts>
75 struct is_size {
76 static constexpr bool value = S == count_args<Ts...>::size;
77 };
78
85 template <size_t S, typename... Ts>
86 struct is_at_least {
87 static constexpr bool value = count_args<Ts...>::size >= S;
88 };
89
97 template <size_t S, bool enable, typename... As>
98 struct packer {
99 };
100
101 template <size_t S, typename A, typename... As>
102 struct packer<S, false, A, As...> {
103 template <typename Tuple>
104 static auto pack(const Tuple &packed, const A &arg, const As&... args) {
105 return packer<S, is_size<S, As...>::value, As...>::pack(std::tuple_cat(packed, std::make_tuple(arg)), args...);
106 }
107 };
108
109 template <size_t S, typename... As>
110 struct packer<S, true, As...> {
111 template <typename Tuple>
112 static auto pack(const Tuple &packed, const As&... args) {
113 return std::make_tuple(packed, args...);
114 }
115 };
116
126 template <size_t S, typename... As>
127 auto pack(const As&... args) {
128 static_assert(is_at_least<S, As...>::value, "Not enough arguments provided to pack()");
129
130 return packer<S, is_size<S, As...>::value, As...>::pack(std::make_tuple(), args...);
131 }
132
142 template <typename F, typename Tuple, std::size_t... I>
143 auto unpack(const F &fn, const Tuple &args, std::index_sequence<I...>) {
144 return fn(std::get<I>(args)...);
145 }
146
147 template <typename F, typename Tuple>
148 auto unpack(const F &fn, const Tuple &args) {
149 constexpr auto size = std::tuple_size<Tuple>::value;
150 return unpack(fn, args, std::make_index_sequence<size>());
151 }
152
153 } // internal
154
155} // live_cells
156
157#endif /* LIVE_CELLS_UTIL_HPP */
Definition boolean.hpp:26
constant_cell< T > value(const T &value)
Definition constant_cell.hpp:132