18cbe371cSRiver Riddle //===- TypeTraitsTest.cpp - type_traits unit tests ------------------------===//
28cbe371cSRiver Riddle //
38cbe371cSRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48cbe371cSRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
58cbe371cSRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68cbe371cSRiver Riddle //
78cbe371cSRiver Riddle //===----------------------------------------------------------------------===//
88cbe371cSRiver Riddle
98cbe371cSRiver Riddle #include "llvm/ADT/STLExtras.h"
108cbe371cSRiver Riddle #include "gtest/gtest.h"
118cbe371cSRiver Riddle
128cbe371cSRiver Riddle using namespace llvm;
138cbe371cSRiver Riddle
148cbe371cSRiver Riddle //===----------------------------------------------------------------------===//
158cbe371cSRiver Riddle // function_traits
168cbe371cSRiver Riddle //===----------------------------------------------------------------------===//
178cbe371cSRiver Riddle
188cbe371cSRiver Riddle namespace {
198cbe371cSRiver Riddle /// Check a callable type of the form `bool(const int &)`.
208cbe371cSRiver Riddle template <typename CallableT> struct CheckFunctionTraits {
218cbe371cSRiver Riddle static_assert(
22*6aa050a6SNathan James std::is_same_v<typename function_traits<CallableT>::result_t, bool>,
238cbe371cSRiver Riddle "expected result_t to be `bool`");
248cbe371cSRiver Riddle static_assert(
25*6aa050a6SNathan James std::is_same_v<typename function_traits<CallableT>::template arg_t<0>,
26*6aa050a6SNathan James const int &>,
278cbe371cSRiver Riddle "expected arg_t<0> to be `const int &`");
288cbe371cSRiver Riddle static_assert(function_traits<CallableT>::num_args == 1,
298cbe371cSRiver Riddle "expected num_args to be 1");
308cbe371cSRiver Riddle };
318cbe371cSRiver Riddle
328cbe371cSRiver Riddle /// Test function pointers.
338cbe371cSRiver Riddle using FuncType = bool (*)(const int &);
348cbe371cSRiver Riddle struct CheckFunctionPointer : CheckFunctionTraits<FuncType> {};
358cbe371cSRiver Riddle
368cbe371cSRiver Riddle /// Test method pointers.
378cbe371cSRiver Riddle struct Foo {
388cbe371cSRiver Riddle bool func(const int &v);
398cbe371cSRiver Riddle };
408cbe371cSRiver Riddle struct CheckMethodPointer : CheckFunctionTraits<decltype(&Foo::func)> {};
418cbe371cSRiver Riddle
428cbe371cSRiver Riddle /// Test lambda references.
__anon49e6b1000202(const int &v) 4392f1562fSRiver Riddle LLVM_ATTRIBUTE_UNUSED auto lambdaFunc = [](const int &v) -> bool {
4492f1562fSRiver Riddle return true;
4592f1562fSRiver Riddle };
468cbe371cSRiver Riddle struct CheckLambda : CheckFunctionTraits<decltype(lambdaFunc)> {};
478cbe371cSRiver Riddle
488cbe371cSRiver Riddle } // end anonymous namespace
498cbe371cSRiver Riddle
508cbe371cSRiver Riddle //===----------------------------------------------------------------------===//
518cbe371cSRiver Riddle // is_detected
528cbe371cSRiver Riddle //===----------------------------------------------------------------------===//
538cbe371cSRiver Riddle
548cbe371cSRiver Riddle namespace {
558cbe371cSRiver Riddle struct HasFooMethod {
foo__anon49e6b1000311::HasFooMethod568cbe371cSRiver Riddle void foo() {}
578cbe371cSRiver Riddle };
588cbe371cSRiver Riddle struct NoFooMethod {};
598cbe371cSRiver Riddle
608cbe371cSRiver Riddle template <class T> using has_foo_method_t = decltype(std::declval<T &>().foo());
618cbe371cSRiver Riddle
628cbe371cSRiver Riddle static_assert(is_detected<has_foo_method_t, HasFooMethod>::value,
638cbe371cSRiver Riddle "expected foo method to be detected");
648cbe371cSRiver Riddle static_assert(!is_detected<has_foo_method_t, NoFooMethod>::value,
658cbe371cSRiver Riddle "expected no foo method to be detected");
668cbe371cSRiver Riddle } // end anonymous namespace
67