1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
// Copyright (c) 2021 René Kijewski <rene.[SURNAME]@fu-berlin.de>
// All rights reserved.
//
// This software and the accompanying materials are made available under
// the terms of the ISC License which is available in the project root as LICENSE-ISC, AND/OR
// the terms of the MIT License which is available at in the project root as LICENSE-MIT, AND/OR
// the terms of the Apache License, Version 2.0 which is available in the project root as LICENSE-APACHE.
//
// You have to accept AT LEAST one of the aforementioned licenses to use, copy, modify, and/or distribute this software.
// At your will you may redistribute the software under the terms of only one, two, or all three of the aforementioned licenses.
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![no_std]
#![cfg_attr(
feature = "feature-const_fn_trait_bound",
feature(const_fn_trait_bound)
)]
#![cfg_attr(
feature = "feature-generic_associated_types",
feature(generic_associated_types)
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! Utility library to work with tuples.
//!
//! ## Features:
//!
//! * **Test if all elements are [Ok]: [all_ok()]**
//!
//! `features = ["all-ok"]`, included by default
//!
//! ```
//! # use tupleops::all_ok;
//! # fn good(value: i32) -> Result<i32, i32> {
//! # Ok(value)
//! # }
//! # fn bad(value: i32) -> Result<i32, i32> {
//! # Err(value)
//! # }
//! assert_eq!(
//! all_ok((good(1), good(2), good(3))),
//! Ok((1, 2, 3)),
//! );
//! assert_eq!(
//! all_ok((good(1), bad(2), good(3))),
//! Err((Ok(1), Err(2), Ok(3)))
//! );
//! ```
//!
//! * **Test if all elements are [Some]: [all_some()]**
//!
//! `features = ["all-some"]`, included by default
//!
//! ```
//! # use tupleops::all_some;
//! assert_eq!(
//! all_some((Some(1), Some(2), Some(3))),
//! Ok((1, 2, 3))
//! );
//! assert_eq!(
//! all_some((Some(1), Option::<()>::None, Some(3))),
//! Err((Some(1), None, Some(3)))
//! );
//! ```
//!
//! * **Prepend an element to a tuple: [prepend()]**
//!
//! `features = ["prepend"]`, included by default
//!
//! ```
//! # use tupleops::prepend;
//! assert_eq!(prepend(1, (2, 3, 4)), (1, 2, 3, 4));
//! ```
//!
//! * **Append an element to a tuple: [append()]**
//!
//! `features = ["append"]`, included by default
//!
//! ```
//! # use tupleops::append;
//! assert_eq!(append((1, 2, 3), 4), (1, 2, 3, 4));
//! ```
//!
//! * **Concatenate two tuples: [concat_tuples()]**
//!
//! `features = ["concat"]`, included by default
//!
//! ```
//! # use tupleops::concat_tuples;
//! assert_eq!(concat_tuples((1, 2), (3, 4, 5)), (1, 2, 3, 4, 5));
//! ```
//!
//! * **Concatenate multiple tuples: [concat_many()]**
//!
//! `features = ["concat-many"]`, included by default
//!
//! ```
//! # use tupleops::concat_many;
//! assert_eq!(concat_many(((), (1,), (2, 3,), (4, 5, 6))), (1, 2, 3, 4, 5, 6));
//! ```
//!
//! * **Turn a reference to a tuple to a tuple of references: [ref_tuple()]**
//!
//! `features = ["ref"]`, included by default
//!
//! ```
//! # use tupleops::ref_tuple;
//! assert_eq!(ref_tuple(&(1, 2, 3)), (&1, &2, &3));
//! ```
//!
//! * **Turn a reference to a mutable tuple to a tuple of mutable references: [ref_mut_tuple()]**
//!
//! `features = ["ref-mut"]`, included by default
//!
//! ```
//! # use tupleops::ref_mut_tuple;
//! assert_eq!(ref_mut_tuple(&mut (1, 2, 3)), (&mut 1, &mut 2, &mut 3));
//! ```
//!
//! * **Extract the first element of a tuple: [unprepend()]**
//!
//! `features = ["unprepend"]`, included by default
//!
//! ```
//! # use tupleops::unprepend;
//! assert_eq!(unprepend((1, 2, 3, 4)), (1, (2, 3, 4)));
//! ```
//!
//! * **Extract the last element of a tuple: [unappend()]**
//!
//! `features = ["unappend"]`, included by default
//!
//! ```
//! # use tupleops::unappend;
//! assert_eq!(unappend((1, 2, 3, 4)), ((1, 2, 3), 4));
//! ```
//!
//! * **Call a function with the tuple members as arguments: [apply()]**
//!
//! `features = ["apply"]`, included by default
//!
//! ```
//! # use tupleops::apply;
//! fn add3(a: u32, b: u32, c: u32) -> u32 { a + b + c }
//!
//! let tpl3 = (1, 2, 3);
//! assert_eq!(apply(&add3, tpl3), 6);
//! ```
//!
//! * **Element-wise wrap the element of a tuple in [Option]: [option_tuple()]**
//!
//! `features = ["option"]`, included by default
//!
//! ```
//! # use tupleops::option_tuple;
//! assert_eq!(option_tuple(Some((1, 2, 3))), (Some(1), Some(2), Some(3)));
//! ```
//!
//! * **Get the length of a tuple: [length()]**
//!
//! `features = ["length"]`, included by default
//!
//! ```
//! # use tupleops::TupleLength;
//! assert_eq!(<(u8, u16, u32) as TupleLength>::LENGTH, 3);
//! ```
//!
//! * **Map a tuple: [map_tuple()]**
//!
//! `features = ["[map](map_tuple)"]`, **not** included by default,
//! because it needs the unstable feature
//! [`generic_associated_types` (GAT)](https://github.com/rust-lang/rust/issues/44265).
//!
//! ```
//! # #![feature(generic_associated_types)]
//! # use tupleops::{TupleMapper, map_tuple};
//! struct MyTupleEnum(usize);
//!
//! impl TupleMapper for MyTupleEnum {
//! type MapElem<Type> = (usize, Type);
//!
//! fn map_elem<Elem>(&mut self, elem: Elem) -> Self::MapElem<Elem> {
//! let index = self.0;
//! self.0 += 1;
//! (index, elem)
//! }
//! }
//!
//! assert_eq!(
//! map_tuple(MyTupleEnum(1), ("hello", "world", "!")),
//! ((1, "hello"), (2, "world"), (3, "!")),
//! )
//! ```
//!
//! When used in libraries, you should probably use `default-features = false`, and only opt in
//! to the features you actually need.
//!
//! ## Supported tuple lengths:
//!
//! By default the selected operations are implemented to tuples upto a length of 16 elements
//! (`features = ["default-len"]`).
//! You can specify a higher limit by using `feature = ["X"]`, where X can be
//! 8, 16, 32, 64, 96, 128, 160, 192, 224, or 256. A higher number includes all lower numbers.
//!
//! **Beware:** `features = ["256"]` needs about 5 GB of RAM to compile the module,
//! so only use it if you actually need it.
mod tpl_all_ok;
mod tpl_all_some;
mod tpl_append;
mod tpl_apply;
mod tpl_concat;
mod tpl_concat_many;
mod tpl_length;
mod tpl_map;
mod tpl_option;
mod tpl_prepend;
mod tpl_ref;
mod tpl_ref_mut;
mod tpl_tuple;
mod tpl_unappend;
mod tpl_unprepend;
pub use tpl_all_ok::*;
pub use tpl_all_some::*;
pub use tpl_append::*;
pub use tpl_apply::*;
pub use tpl_concat::*;
pub use tpl_concat_many::*;
pub use tpl_length::*;
pub use tpl_map::*;
pub use tpl_option::*;
pub use tpl_prepend::*;
pub use tpl_ref::*;
pub use tpl_ref_mut::*;
pub use tpl_tuple::*;
pub use tpl_unappend::*;
pub use tpl_unprepend::*;
#[doc(hidden)]
#[macro_export]
macro_rules! do_impl {
($feature_name:literal, $macro_name:ident, { $($body:tt)* }) => {
pub use r#impl::*;
#[cfg(not(feature = $feature_name))]
mod r#impl {}
#[cfg(feature = $feature_name)]
mod r#impl {
$($body)*
::tupleops_macros::$macro_name!(1..=4);
#[cfg(feature = "8")]
::tupleops_macros::$macro_name!(5..=8);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "16")]
::tupleops_macros::$macro_name!(9..=16);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "32")]
::tupleops_macros::$macro_name!(17..=32);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "64")]
::tupleops_macros::$macro_name!(33..=64);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "96")]
::tupleops_macros::$macro_name!(65..=96);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "128")]
::tupleops_macros::$macro_name!(97..=128);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "160")]
::tupleops_macros::$macro_name!(129..=160);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "192")]
::tupleops_macros::$macro_name!(161..=192);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "224")]
::tupleops_macros::$macro_name!(193..=224);
#[cfg(not(feature = "dont_hurt_yourself_by_using_all_features"))]
#[cfg(feature = "256")]
::tupleops_macros::$macro_name!(225..=256);
}
};
}