An open API service indexing awesome lists of open source software.

https://github.com/zxshady/extra_traits


https://github.com/zxshady/extra_traits

Last synced: 6 months ago
JSON representation

Awesome Lists containing this project

README

          

# extra_traits

simple library for some missing type traits I always need when making unreadable meta programs.

Minimum C++11 with support for variadic macros and variaidc templates and type traits library.

all these are available in namespace `zxshady::tmp` and all type traits have _t unconditionally but it also has _v shortcuts if available.

has_operator_*

each of these has their own header for minimizing includes you can look at the file names at `include/zxshady/has_operators/`

| Category | Operator |
|---|---|
| Increment/Decrement | post_increment |
| | pre_decrement |
| | pre_increment |
| | post_increment |
| Unary | dereference |
| | complement |
| | unary_minus |
| | unary_plus |
| Bitwise | bit_and |
| | bit_or |
| | bit_xor |
| | bit_and_assign |
| | bit_or_assign |
| | bit_xor_assign |
| Shift | left_shift |
| | left_shift_assign |
| | right_shift |
| | right_shift_assign |
| Logical | logical_and |
| | logical_not |
| | logical_or |
| Arithmetic | plus |
| | minus |
| | modulus |
| | multiply |
| | divide |
| | plus_assign |
| | minus_assign |
| | modulus_assign |
| | multiply_assign |
| | divide_assign |
| Comparison | equal_to |
| | not_equal_to |
| | less |
| | less_equal |
| | greater |
| | greater_equal |
| Accessors | arrow |
| | subscript |
| | addressof |
| Functor | call |

each has_operator_XXX has 4 static members

```cpp
has_operator_XXX::member; // whether it is a member function
has_operator_XXX::free; // whether it is a free function
has_operator_XXX::overloaded; // equalivent to member || free
has_operator_XXX::value; // whether it has the operator or not
```

simple type aliases

```cpp

template
using index_c = std::integral_constant;

template
using alignof_c = std::integral_constant;

template
using sizeof_c = std::integral_constant;

// this is avaiable in C++17
template
using constant = std::integral_constant;

template
using t_ = typename Trait::type; // shortcut trait

template
constexpr bool v_ = Trait::value; // shortcut variable

_
template
using always_false = std::false_type; (var alias : false_v)

template
using always_true = std::true_type; (var alias: true_v)

template
using type_t = T;

template // since C++14
using is_inheritable = bool_constant && !std::is_final_v >;

template
struct empty_base {};

// does not report true for bool
template
using is_signed_integral = std::bool_constant<
!std::is_same_v> && std::is_integral_v && std::is_signed_v>;

// does not report true for bool
template
using is_unsigned_integral = std::bool_constant> && std::is_integral_v && std::is_unsigned_v>;

```

utility functions

```cpp
as_const(T&) // same as std::as__const
as_volatile(T&)
as_cv(T&)
forward_like(T&)

```

Standard Library Features in previous C++ versions
```cpp
// in "extra_traits/standard_library_features.hpp"
std::disjunction
std::conjunction
std::negation
std::is_null_pointer
std::bool_constant
std::type_identity
std::integer_sequence
std::remove_cvref
std::void_t
std::is_scoped_enum
std::is_bounded_array
std::is_unbounded_array
```

utility traits

```cpp
template
inherit_if::type // if Condition is true then inherit from Base otherwise inherit from empty_base
```

non-short circuiting `disjunction` and `conjunction`

```cpp
and_::value;
or_::value;

```

constructing predicates
```cpp
template class... Predicates>
struct predicate_and;

template class... Predicates>
struct predicate_or;

template class Predicates>
struct predicate_not;

// each one of them has a member called
// 'invoke' that is used like this
using is_const_integer = predicate_and;
static_assert(template is_const_integer::invoke::value);

```

unary traits
```cpp
is_scoped_enum::value
is_unscoped_enum::value
```

modifying traits
```cpp
remove_all_pointers -> int;
remove_all_pointers -> float[];
```

## Qualifications Copying and Maniplating Traits

- from [paper](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1016r0.pdf)

*Note each `copy_xxxxx` trait has a corrosponding `clone_xxxxx` (except `copy_signedness` there is no corrosponding `clone_signedness`)* which is equal to `copy_xxxxx>`*


copy_const&ltFrom,To&gt

Show Table

```cpp
From -> To
const From -> const To
volatile From -> To
const volatile From -> const To
--------------------------------
From& -> To
const From& -> To
volatile From& -> To
const volatile From& -> To
--------------------------------
From&& -> To
const From&& -> To
volatile From&& -> To
const volatile From&& -> To
```


copy_volatile&ltFrom,To&gt

Show Table

```cpp
From -> To
const From -> To
volatile From -> volatile To
const volatile From -> volatile To
--------------------------------
From& -> To
const From& -> To
volatile From& -> To
const volatile From& -> To
--------------------------------
From&& -> To
const From&& -> To
volatile From&& -> To
const volatile From&& -> To
```

## copy_cv

is a short cut for copy_const_t
&ltFrom,copy_volatile_t&ltFrom,To&gt&gt

Show Table
From -> To
const From -> const To
volatile From -> volatile To
const volatile From -> const volatile To
--------------------------------
From& -> To
const From& -> To
volatile From& -> To
const volatile From& -> To
--------------------------------
From&& -> To
const From&& -> To
volatile From&& -> To
const volatile From&& -> To


copy_reference&ltFrom,To&gt

Show Table

# NOTE: this uses reference collapsing rules, which may not be wanted if you do not want it then use `clone_reference`.
```cpp
From -> To
const From -> To
volatile From -> To
const volatile From -> To
--------------------------------
From& -> To&
const From& -> To&
volatile From& -> To&
const volatile From& -> To&
--------------------------------
From&& -> To&&
const From&& -> To&&
volatile From&& -> To&&
const volatile From&& -> To&&
```

## copy_cvref
a short cut for "copy_reference, remove_reference_t\>>>"


copy_pointer&ltFrom,To&gt

Show Table

```cpp
From -> To
const From -> To
volatile From -> To
const volatile From -> To
--------------------------------
From* -> To*
From*const -> To*
From*volatile -> To*
From*const volatile -> To*
```


copy_all_pointers&ltFrom,To&gt

Show Table

```cpp
From -> To
const From -> To
volatile From -> To
const volatile From -> To
--------------------------------
From** -> To**
From**const -> To**
From**volatile -> To**
From**const volatile -> To**
```


copy_signedness&ltFrom,To&gt

Show Table

```cpp
signed From -> signed To
const signed From -> signed To
volatile signed From -> signed To
const volatile signed From -> signed To
--------------------------------
unsigned From -> unsigned To
const unsigned From -> unsigned To
volatile unsigned From -> unsigned To
const volatile unsigned From -> unsigned To
--------------------------------
char -> [to's sign does not change] To
const char -> [to's sign does not change] To
volatile char -> [to's sign does not change] To
const volatile char -> [to's sign does not change] To

```

### least_size_[u]int

gets the smallest unsigned or signed integer type that can hold this value

Show Example (it can differ depending on the size of types)

```cpp
least_size_uint_t<200>; // unsigned char
least_size_int_t<500>; // signed short
```

### remove_[l|r]value_reference

removes the reference qualifier if it is an L or R value respectivly.

Show Table

```cpp
typename remove_lvalue_reference::type; // int
typename remove_lvalue_reference::type; // int
typename remove_lvalue_reference::type; // int&&

typename remove_rvalue_reference::type; // int
typename remove_rvalue_reference::type; // int&
typename remove_rvalue_reference::type; // int

```

### ZXSHADY_FWD ZXSHADY_MOV macros

the first does a std::forward and the second does std::move, why does these exist? well it is for compile time performance as std::forward is relativly expensive for a glorified `static_cast` these macros fix this issue these macros are in the `extra_traits/macros.hpp` header file.

Show Example

```cpp

[](auto&& vals) {
std::forward(vals);
// vs
ZXSHADY_FWD(vals)

std::move(vals);
// vs
ZXSHADY_MOV(vals);
}

```


is_explicitly_constructible


tests for whether the type is explicitly constructible given the Args

*it also has `is_explicitly_default_constructible`,`is_explicitly_copy_constructible` and `is_explicitly_move_constructible`*
```cpp
using namespace zxshady::tmp;

struct A {
explicit A(int,int);
/*implicit*/ A(int,int,int);
};
is_explicitly_constructible::value; // true
is_explicitly_constructible
::value; // false
is_explicitly_constructible
::value; // false

```
## is_implicitly_constructible

the opposite of [is_explicitly_constructible\](#is_explicitly_constructible) it checks whether the type is implictly constructible

*it also has `is_implicitly_default_constructible`,`is_implicitly_copy_constructible` and `is_implicitly_move_constructible`*
```cpp
using namespace zxshady::tmp;

struct A {
explicit A(int,int);
/*implicit*/ A(int,int,int);
};
is_implicitly_constructible
::value; // false
is_implicitly_constructible
::value; // true
is_implicitly_constructible
::value; // false
```

## type_list

a container that contains types.

## *static members*


size
a static constant equal to `sizeof...(Types)`

```cpp
using List = type_list;
static_assert(List::size == 3);
```


is_empty
a static boolean constant equal to size == 0

```cpp
using List = type_list;
using List2 = type_list<>;
static_assert(!List::is_empty);
static_assert(List2::is_empty);
```


at&ltIndex&gt
index into the types from the list.
if the index is out of bounds a `static_assert` will fire.

```cpp
using List = type_list;
static_assert(std::is_same_v>);
```


at_or&ltIndex,OrType&gt
index into the types from the list. if the index is out of bounds
then returns the OrType instead of failing.

```cpp
using List = type_list;
static_assert(std::is_same_v>);
static_assert(std::is_same_v>);
```


front
equal to `List::template at&lt0&gt`

*note this member does not exist if is_empty is true*

```cpp
using List = type_list;
static_assert(std::is_same_v);
```


back
equal to `List::template at&ltsize-1&gt`

*note this member does not exist if is_empty is true*

```cpp
using List = type_list;
static_assert(std::is_same_v);
```


operator+
does concatenation of 2 lists

```cpp
using List1 = type_list;
using List2 = type_list;
static_assert(std::is_same_v);
```


reverse
reverses the list

```cpp
using List = type_list;
using NewList = List::reverse;
static_assert(std::is_same_v);
static_assert(std::is_same_v);
```


pop_front
pops the first type in the list

```cpp
using List = type_list;
using NewList = List::pop_front;
static_assert(std::is_same_v);
```


pop_back
pops the last type in the list

```cpp
using List = type_list;
using NewList = List::pop_back;
static_assert(std::is_same_v);
```


transform&ltTransformTrait&gt
apply the TransformTrait to every type in the list,

```cpp
using List = type_list;
static_assert(std::is_same_v,type_list >);
```


rename_to&ltTemplate&gt

```cpp
using List = type_list>;

static_assert(std::is_same_v,std::vector> >);
```


insert&ltIndex,Types...&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list >);
```


erase&ltIndex&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list >);
```


erase_if&ltPredicate&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list >);
```


slice&ltBegin,End = size&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v>,type_list<>>);

```


drop_first&ltCount&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v>,type_list<>>);

```


drop_last&ltCount&gt

```cpp
using List = type_list;

static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v,type_list>);
static_assert(std::is_same_v>,type_list<>>);
```


replace_at&ltIndex,T&gt

```cpp
using List = type_list;

static_assert(std::is_same_v, type_list>);
static_assert(std::is_same_v, type_list>);
static_assert(std::is_same_v, type_list>);

```

## Free Functions


find_if&ltPredicate,Pos = 0&gt
*note* returns std::size_t(-1) on not found

```cpp
using List = type_list;

static_assert(find_if(List{}) == 2);
static_assert(find_if(List{}) == 3);

```


find&ltT,Pos = 0&gt

```cpp
using List = type_list;

static_assert(find(List{}) == std::size_t(-1));
static_assert(find(List{}) == 1);

```


type_list_repeat_n&ltN,T&gt
returns a type_list with N Ts in it

```cpp
static_assert(std::is_same_v, type_list>);
static_assert(std::is_same_v, type_list<>>);
static_assert(std::is_same_v, type_list>);
```

there is still more methods.

documentation incomplete...