Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/src/__support/CPP/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "src/__support/CPP/type_traits/enable_if.h"
#include "src/__support/CPP/type_traits/false_type.h"
#include "src/__support/CPP/type_traits/integral_constant.h"
#include "src/__support/CPP/type_traits/invoke_result.h"
#include "src/__support/CPP/type_traits/is_arithmetic.h"
#include "src/__support/CPP/type_traits/is_array.h"
#include "src/__support/CPP/type_traits/is_base_of.h"
Expand All @@ -32,6 +33,7 @@
#include "src/__support/CPP/type_traits/is_lvalue_reference.h"
#include "src/__support/CPP/type_traits/is_member_pointer.h"
#include "src/__support/CPP/type_traits/is_null_pointer.h"
#include "src/__support/CPP/type_traits/is_object.h"
#include "src/__support/CPP/type_traits/is_pointer.h"
#include "src/__support/CPP/type_traits/is_reference.h"
#include "src/__support/CPP/type_traits/is_rvalue_reference.h"
Expand Down
90 changes: 90 additions & 0 deletions libc/src/__support/CPP/type_traits/invoke_result.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//===-- invoke_result type_traits -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INVOKE_RESULT_H
#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INVOKE_RESULT_H

#include "src/__support/CPP/type_traits/decay.h"
#include "src/__support/CPP/type_traits/enable_if.h"
#include "src/__support/CPP/type_traits/false_type.h"
#include "src/__support/CPP/type_traits/is_base_of.h"
#include "src/__support/CPP/type_traits/is_function.h"
#include "src/__support/CPP/type_traits/true_type.h"
#include "src/__support/CPP/utility/declval.h"
#include "src/__support/CPP/utility/forward.h"

// BEWARE : this implementation is not fully conformant as it doesn't take
// `cpp::reference_wrapper` into account.

namespace __llvm_libc::cpp {

// invoke_result

namespace detail {
template <class T> struct is_reference_wrapper : cpp::false_type {};

// Disable specialization on `cpp::reference_wrapper` as it is not yet
// implemented.

// template <class U> struct
// is_reference_wrapper<cpp::reference_wrapper<U>> : cpp::true_type {};

template <class T> struct invoke_impl {
template <class F, class... Args>
static auto call(F &&f, Args &&...args)
-> decltype(cpp::forward<F>(f)(cpp::forward<Args>(args)...));
};

template <class B, class MT> struct invoke_impl<MT B::*> {
template <class T, class Td = cpp::decay_t<T>,
class = cpp::enable_if_t<cpp::is_base_of_v<B, Td>>>
static auto get(T &&t) -> T &&;

template <class T, class Td = cpp::decay_t<T>,
class = cpp::enable_if_t<is_reference_wrapper<Td>::value>>
static auto get(T &&t) -> decltype(t.get());

template <class T, class Td = cpp::decay_t<T>,
class = cpp::enable_if_t<!cpp::is_base_of_v<B, Td>>,
class = cpp::enable_if_t<!is_reference_wrapper<Td>::value>>
static auto get(T &&t) -> decltype(*cpp::forward<T>(t));

template <class T, class... Args, class MT1,
class = cpp::enable_if_t<cpp::is_function_v<MT1>>>
static auto call(MT1 B::*pmf, T &&t, Args &&...args)
-> decltype((invoke_impl::get(cpp::forward<T>(t)).*
pmf)(cpp::forward<Args>(args)...));

template <class T>
static auto call(MT B::*pmd, T &&t)
-> decltype(invoke_impl::get(cpp::forward<T>(t)).*pmd);
};

template <class F, class... Args, class Fd = typename cpp::decay_t<F>>
auto INVOKE(F &&f, Args &&...args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this all caps?

Copy link
Contributor Author

@gchatelet gchatelet Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a concept defined by the standard "23.14.3 [func.require]". INVOKE (all caps) serves as a foundation for defining std::invoke and std::invoke_result.

-> decltype(invoke_impl<Fd>::call(cpp::forward<F>(f),
cpp::forward<Args>(args)...));

template <typename AlwaysVoid, typename, typename...> struct invoke_result {};
template <typename F, typename... Args>
struct invoke_result<decltype(void(detail::INVOKE(cpp::declval<F>(),
cpp::declval<Args>()...))),
F, Args...> {
using type =
decltype(detail::INVOKE(cpp::declval<F>(), cpp::declval<Args>()...));
};
} // namespace detail

template <class F, class... ArgTypes>
struct invoke_result : detail::invoke_result<void, F, ArgTypes...> {};

template <class F, class... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;

} // namespace __llvm_libc::cpp

#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_INVOKE_RESULT_H
30 changes: 30 additions & 0 deletions libc/src/__support/CPP/type_traits/is_object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===-- is_object type_traits -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_OBJECT_H
#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_OBJECT_H

#include "src/__support/CPP/type_traits/bool_constant.h"
#include "src/__support/CPP/type_traits/is_array.h"
#include "src/__support/CPP/type_traits/is_class.h"
#include "src/__support/CPP/type_traits/is_scalar.h"
#include "src/__support/CPP/type_traits/is_union.h"
#include "src/__support/macros/attributes.h"

namespace __llvm_libc::cpp {

// is_object
template <class T>
struct is_object
: cpp::bool_constant<cpp::is_scalar_v<T> || cpp::is_array_v<T> ||
cpp::is_union_v<T> || cpp::is_class_v<T>> {};
template <class T>
LIBC_INLINE_VAR constexpr bool is_object_v = is_object<T>::value;

} // namespace __llvm_libc::cpp

#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_IS_OBJECT_H
3 changes: 3 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ libc_support_library(
"src/__support/CPP/type_traits/enable_if.h",
"src/__support/CPP/type_traits/false_type.h",
"src/__support/CPP/type_traits/integral_constant.h",
"src/__support/CPP/type_traits/invoke_result.h",
"src/__support/CPP/type_traits/is_arithmetic.h",
"src/__support/CPP/type_traits/is_array.h",
"src/__support/CPP/type_traits/is_base_of.h",
Expand All @@ -309,6 +310,7 @@ libc_support_library(
"src/__support/CPP/type_traits/is_lvalue_reference.h",
"src/__support/CPP/type_traits/is_member_pointer.h",
"src/__support/CPP/type_traits/is_null_pointer.h",
"src/__support/CPP/type_traits/is_object.h",
"src/__support/CPP/type_traits/is_pointer.h",
"src/__support/CPP/type_traits/is_reference.h",
"src/__support/CPP/type_traits/is_rvalue_reference.h",
Expand All @@ -332,6 +334,7 @@ libc_support_library(
"src/__support/CPP/type_traits/type_identity.h",
"src/__support/CPP/type_traits/void_t.h",
"src/__support/CPP/utility/declval.h",
"src/__support/CPP/utility/forward.h",
],
deps = [
":__support_macros_attributes",
Expand Down