type_traits: basic number tests
This commit is contained in:
commit
4e3152b5df
38
CMakeLists.txt
Normal file
38
CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
###############################################################################
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
project(cruft-cxx CXX)
|
||||
|
||||
|
||||
###############################################################################
|
||||
list (APPEND sources
|
||||
src/type_traits
|
||||
src/exception
|
||||
src/exception.cpp
|
||||
)
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
add_library (cruft-cxx STATIC ${sources})
|
||||
|
||||
|
||||
###############################################################################
|
||||
option (TESTS "enable unit testing" ON)
|
||||
|
||||
|
||||
if (TESTS)
|
||||
include (CTest)
|
||||
enable_testing ()
|
||||
|
||||
foreach (t type_traits exception)
|
||||
string(REPLACE "/" "_" name "test/${t}")
|
||||
add_executable(cxx_${name} test/${t}.cpp)
|
||||
target_link_libraries(cxx_${name} PRIVATE cruft-cxx cruft)
|
||||
target_include_directories(cxx_${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_test(NAME cxx_${name} COMMAND cxx_${name})
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
configure_file(libcruft-cxx.pc.in libcruft-cxx.pc)
|
||||
configure_file(Doxyfile.in Doxyfile)
|
2429
Doxyfile.in
Normal file
2429
Doxyfile.in
Normal file
File diff suppressed because it is too large
Load Diff
3
README.adoc
Normal file
3
README.adoc
Normal file
@ -0,0 +1,3 @@
|
||||
A naive re-implementation of some components of the C++ standard library.
|
||||
|
||||
There are no external dependencies for the library.
|
12
libcruft-cxx.pc.in
Normal file
12
libcruft-cxx.pc.in
Normal file
@ -0,0 +1,12 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libcruft-crypto
|
||||
Description: A naive C++ cryptographic library
|
||||
URL: http://nerdcruft.net/
|
||||
Version: @VERSION@
|
||||
Requires: libcruft
|
||||
Libs: -L${libdir}
|
||||
Cflags: -I${includedir}
|
0
src/exception.cpp
Normal file
0
src/exception.cpp
Normal file
179
src/type_traits
Normal file
179
src/type_traits
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace cruft::cxx {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, T Value>
|
||||
struct integral_constant {
|
||||
static constexpr T value = Value;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
struct true_type : integral_constant<bool,true> {};
|
||||
struct false_type : integral_constant<bool,false> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
namespace detail {
|
||||
template <bool ...Values>
|
||||
struct _or : integral_constant<bool, (Values || ...)> {};
|
||||
|
||||
template <bool ...Values>
|
||||
struct _and : integral_constant<bool, (Values && ...)> {};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename, typename> struct is_same : false_type {};
|
||||
template <typename T> struct is_same<T,T> : true_type {};
|
||||
template <typename A, typename B>
|
||||
constexpr auto is_same_v = is_same<A,B>::value;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T> struct remove_const { using type = T; };
|
||||
template <typename T> struct remove_const<const T> { using type = T; };
|
||||
template <typename T> using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T> struct remove_volatile { using type = T; };
|
||||
template <typename T> struct remove_volatile<volatile T> { using type = T; };
|
||||
template <typename T> using remove_volatile_t = typename remove_volatile<T>::type;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct remove_cv {
|
||||
using type = remove_volatile_t<remove_const_t<T>>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_cv_t = typename remove_cv<T>::type;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct _is_integral : false_type {};
|
||||
|
||||
template <> struct _is_integral<bool> : true_type {};
|
||||
|
||||
template <> struct _is_integral<short> : true_type {};
|
||||
template <> struct _is_integral<int> : true_type {};
|
||||
template <> struct _is_integral<long> : true_type {};
|
||||
template <> struct _is_integral<long long> : true_type {};
|
||||
|
||||
template <> struct _is_integral<unsigned short> : true_type {};
|
||||
template <> struct _is_integral<unsigned int> : true_type {};
|
||||
template <> struct _is_integral<unsigned long> : true_type {};
|
||||
template <> struct _is_integral<unsigned long long> : true_type {};
|
||||
|
||||
|
||||
template <> struct _is_integral<char> : true_type {};
|
||||
template <> struct _is_integral<unsigned char> : true_type {};
|
||||
template <> struct _is_integral<signed char> : true_type {};
|
||||
|
||||
#if __cpp_char8_t
|
||||
template <> struct _is_integral<char8_t> : true_type {};
|
||||
#endif
|
||||
template <> struct _is_integral<char16_t> : true_type {};
|
||||
template <> struct _is_integral<char32_t> : true_type {};
|
||||
template <> struct _is_integral<wchar_t> : true_type {};
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct is_integral : detail::_is_integral<remove_cv_t<T>> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
constexpr auto is_integral_v = is_integral<T>::value;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <typename T> struct _is_floating_point : false_type {};
|
||||
template <> struct _is_floating_point<float> : true_type {};
|
||||
template <> struct _is_floating_point<double> : true_type {};
|
||||
template <> struct _is_floating_point<long double> : true_type {};
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct is_floating_point : detail::_is_floating_point<remove_cv_t<T>> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
constexpr auto is_floating_point_v = is_floating_point<T>::value;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct is_arithmetic : detail::_or<
|
||||
is_integral_v<T>,
|
||||
is_floating_point_v<T>
|
||||
> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
constexpr auto is_arithmetic_v = is_arithmetic<T>::value;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct is_fundamental : detail::_or<
|
||||
is_arithmetic_v<T>,
|
||||
is_same_v<T, void>,
|
||||
is_same_v<T, decltype(nullptr)>
|
||||
> {};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <
|
||||
typename T,
|
||||
bool = is_arithmetic_v<T>
|
||||
> struct _is_signed : false_type {};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct _is_signed<T,true> : integral_constant<bool, T(-1) < T(0)> {};
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct is_signed : detail::_is_signed<T> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
constexpr auto is_signed_v = is_signed<T>::value;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct is_unsigned : detail::_and<
|
||||
is_arithmetic_v<T>,
|
||||
!is_signed_v<T>
|
||||
> {};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
constexpr auto is_unsigned_v = is_unsigned<T>::value;
|
||||
};
|
6
test/exception.cpp
Normal file
6
test/exception.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
|
||||
}
|
58
test/type_traits.cpp
Normal file
58
test/type_traits.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
|
||||
#include "src/type_traits"
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
using namespace cruft::cxx;
|
||||
|
||||
// Type comparisons
|
||||
static_assert (is_same_v<int,int>);
|
||||
static_assert (!is_same_v<int,bool>);
|
||||
static_assert (!is_same_v<int,int const>);
|
||||
static_assert (!is_same_v<int&,int>);
|
||||
|
||||
// CV removal
|
||||
static_assert (is_same_v<remove_const<int const>::type, remove_const_t<int const>>);
|
||||
|
||||
static_assert (
|
||||
is_same_v<
|
||||
int,
|
||||
typename remove_const<int const>::type
|
||||
>
|
||||
);
|
||||
|
||||
static_assert (is_same_v<int, remove_volatile_t<int volatile>>);
|
||||
|
||||
static_assert (is_same_v<remove_cv_t<int const volatile>, int>);
|
||||
|
||||
// Integral tests
|
||||
static_assert (is_integral_v<int>);
|
||||
static_assert (is_integral_v<char>);
|
||||
static_assert (is_integral_v<bool>);
|
||||
|
||||
static_assert (is_integral_v<unsigned const volatile>);
|
||||
|
||||
// Floating point tests
|
||||
static_assert (is_floating_point_v<float>);
|
||||
static_assert (is_floating_point_v<double>);
|
||||
static_assert (is_floating_point_v<long double>);
|
||||
static_assert (!is_floating_point_v<char>);
|
||||
static_assert (!is_floating_point_v<bool>);
|
||||
|
||||
// Arithmetic tests
|
||||
static_assert (is_arithmetic_v<float>);
|
||||
static_assert (is_arithmetic_v<unsigned>);
|
||||
static_assert (!is_arithmetic_v<decltype(main)>);
|
||||
|
||||
// Signedness
|
||||
static_assert (is_signed_v<signed>);
|
||||
static_assert (!is_signed_v<unsigned>);
|
||||
static_assert (is_signed_v<float>);
|
||||
static_assert (!is_signed_v<decltype(main)>);
|
||||
|
||||
static_assert (is_unsigned_v<unsigned>);
|
||||
static_assert (!is_unsigned_v<signed>);
|
||||
static_assert (!is_unsigned_v<float>);
|
||||
static_assert (!is_unsigned_v<decltype(main)>);
|
||||
}
|
Loading…
Reference in New Issue
Block a user