-
Notifications
You must be signed in to change notification settings - Fork 0
Type Traits
A recreation of the <type_traits> header in C++98. While most type traits can be implemented on the language level, there are a few features which require modern language features or compiler intrinsics. Notably is_class requires a check against is_union (a compiler intrinsic) so it and the traits which require it to work are not implemented here. Similarly, the _t and _v require using aliases and template variables respectively so could not be implemented.
This file in particular falls victim to the lack of completeness of the Borland template engine, and some traits will be absent on Borland compilers. Where possible in code which uses these I have replaced the need for an invalid trait with an equivalent or stricter trait for Borland compilers, but it is unavoidable that some traits will be missing. Those traits are marked in the table below with an obelus†.
| integral_constant | Compile-time constant of a specified type with a specified value |
| true_type false_type |
dp::integral_constant<bool,true>dp::integral_constant<bool,false>
|
| is_void | Checks if a type is void
|
| is_integral | Checks if a type is an integral type |
| is_floating_point | Checks if a type is a floating point type |
| is_array | Checks if a type is a (C-style) array type |
| is_function† | Checks if a type is a function type |
| is_pointer | Checks if a type is a pointer type |
| is_lvalue_reference | Checks if a type is an lvalue reference type |
| is_member_object_pointer† | Checks if a type is a pointer to a non-static member object |
| is_member_function_pointer† | Checks if a type is a pointer to a non-static member function |
| is_fundamental | Checks if a type is a fundamental type |
| is_arithmetic | Checks if a type is an arithmetic type |
| is_compound | Checks if a type is a compound type |
| is_reference | Checks if a type is a reference type |
| is_member_pointer | Checks if a type is a pointer to a non-static member function or object |
| is_const | Checks if a type is const qualified |
| is_volatile | Checks if a type is volatile qualified |
| is_signed | Checks if a type is a signed arithmetic type |
| is_unsigned | Checks if a type is an unsigned arithmetic type |
| is_bounded_array | Checks if a type is a C-array of known bound |
| is_unbounded_array | Checks if a type is a C-array of unknown bound |
| is_default_constructible† | Checks if a type can be default constructed |
| is_copy_constructible† | Checks if a type can be copy constructed |
| is_assignable† | Checks if a type can be assigned from a specific argument |
| is_copy_assignable† | Checks if a type can be copy assigned |
| is_destructible† | Checks if a type has an accessible destructor |
| is_swappable_with† | Checks if a type is swappable with another given type |
| is_swappable† | Checks if two instances of a type can be swapped |
| rank | Obtains the number of dimensions of an array type |
| extent | Obtains the size of an array type along a specified dimension |
| is_same | Checks if two types are the same |
| is_base_of† | Checks if one type is derived from another type |
| is_convertible† | Checks if one type can be converted to another type |
| remove_const remove_volatile remove_cv |
Removes const, volatile, and const volatile qualification from a type |
| add_const add_volailte add_cv |
Adds const, volatile, and const volatile qualification to a type |
| remove_reference | Removes reference qualification from a type |
| add_lvalue_reference | Adds lvalue reference qualification to a type |
| remove_pointer | Removes a pointer from the given type |
| add_pointer | Adds a pointer to the given type |
| make_signed | Makes the given integral type signed |
| make_unsigned | Makes the given integral type unsigned |
| remove_extent | Removes one extent from an array type |
| remove_all_extents | Removes all extents from an array type |
| decay† | Performs type transformation as if passing the argument to a function by value |
| remove_cvref | Removes const, volatile, and reference qualification from a type |
| enable_if | Conditionally removes a function overload or template specialization from overload resolution |
| conditional | Selects one type or another based on a compile time boolean |
| type_identity | Returns the provided type unchanged |
Note that dp::make_signed and dp::make_unsigned will differ from the spec on Borland compilers for wchar_t
#include <string>
#include <cmath>
#include "cpp98/type_traits.h"
//Function for floating points
template<typename T>
typename dp::enable_if<dp::is_floating_point<T>::value, bool>::type is_even(T in){
return std::fmod(in, 2) == 0; //Not necessarily exact but for the sake of a simple demonstration
}
//Function for integer types
template<typname T>
typename dp::enable_if<dp::is_integral<T>::value, bool>::type is_even(T in){
return in % 2 == 0;
}
int main(){
int x = 100;
double y = 45;
std::string s = "Hello";
is_even(x); //Selects integral overload
is_even(y); //Selects floating point overload
is_even(s); //Cannot select an overload. Compilation fails.
}