From 163d6c102a1a91480aca3be264346898939a496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Dee=20=28J=C5=8Dshin=29?= Date: Thu, 20 Jun 2024 11:25:18 -0700 Subject: [PATCH] wip ctl type traits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am a bit ambivalent about this. is actually not that bad by STL standards, “only” 148 transitive includes for the whole file. The split out variants under __type_traits are also mostly reasonable - e.g. __type_traits/is_same.h only includes 4 other STL files. Many others ask for more, but nothing is all that egregious. I do think we can probably provide an 80–95% solution with a fraction of the footprint in CTL by for example eliding direct struct definitions in favor of the _t or _v variants when the latter are simpler to write, and omitting the more obscure tests in favor of a common core. I don’t think it’s worth splitting things out by file but it might be worth it to e.g. have a type_traits.h and a type_traits_advanced.h or something. --- ctl/type_traits.cc | 71 +++++++++++++++++++++++++ ctl/type_traits.h | 128 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 ctl/type_traits.cc create mode 100644 ctl/type_traits.h diff --git a/ctl/type_traits.cc b/ctl/type_traits.cc new file mode 100644 index 000000000..d181f691f --- /dev/null +++ b/ctl/type_traits.cc @@ -0,0 +1,71 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "type_traits.h" + +// #include +// #define ctl std + +using namespace ctl; + +#undef ctl + +static_assert(is_void_v); +static_assert(is_void_v); +static_assert(is_void_v); + +static_assert(is_same_v); +static_assert(!is_same_v); + +struct A +{ +}; + +using B = A; + +struct C +{ +}; + +struct Base +{ +}; + +struct Derived : Base +{ +}; + +static_assert(is_same_v); +static_assert(is_same_v); +static_assert(!is_same_v); +static_assert(!is_same_v); + +static_assert(is_convertible_v); +static_assert(is_convertible_v); +static_assert(!is_convertible_v); +static_assert(is_convertible_v); +static_assert(!is_convertible_v); + +static_assert(is_convertible_v); +static_assert(is_convertible_v); +static_assert(!is_convertible_v); +static_assert(!is_convertible_v); +static_assert(!is_convertible_v); + +static_assert(is_same_v>); +static_assert(is_same_v>); diff --git a/ctl/type_traits.h b/ctl/type_traits.h new file mode 100644 index 000000000..046e5f95a --- /dev/null +++ b/ctl/type_traits.h @@ -0,0 +1,128 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef COSMOPOLITAN_CTL_TYPE_TRAITS_H_ +#define COSMOPOLITAN_CTL_TYPE_TRAITS_H_ + +#include "utility.h" + +namespace ctl { + +template +struct integral_constant +{ + using value_type = T; + using type = integral_constant; + + static constexpr T value = V; + + constexpr operator value_type() const noexcept + { + return V; + } + + constexpr value_type operator()() const noexcept + { + return V; + } +}; + +using true_type = integral_constant; +using false_type = integral_constant; + +template +struct is_same : false_type +{ +}; + +template +struct is_same : true_type +{ +}; + +template +inline constexpr bool is_same_v = is_same::value; + +template +struct remove_extent +{ + using type = T; +}; + +template +struct remove_extent +{ + using type = T; +}; + +template +struct remove_extent +{ + using type = T; +}; + +template +using remove_extent_t = typename remove_extent::type; + +template +struct remove_cv +{ + using type = T; +}; + +template +struct remove_cv +{ + using type = T; +}; + +template +struct remove_cv +{ + using type = T; +}; + +template +struct remove_cv +{ + using type = T; +}; + +template +using remove_cv_t = typename remove_cv::type; + +template +inline constexpr bool is_void_v = is_same_v>; + +namespace __ { + +template +auto test_returnable(int) -> decltype( + void(static_cast(nullptr)), true_type{}); + +template +auto test_returnable(...) -> false_type; + +template +auto test_implicitly_convertible(int) -> decltype( + void(declval()(declval())), true_type{}); + +template +auto test_implicitly_convertible(...) -> false_type; + +} // namespace __ + +template +struct is_convertible : integral_constant(0))::value && + decltype(__::test_implicitly_convertible(0))::value) || + (is_void_v && is_void_v) +> +{ +}; + +template +inline constexpr bool is_convertible_v = is_convertible::value; + +} // namespace ctl + +#endif // COSMOPOLITAN_CTL_TYPE_TRAITS_H_