/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_TYPE_TRAITS_H_
#define RTC_BASE_TYPE_TRAITS_H_

#include <cstddef>
#include <type_traits>

namespace rtc {

// Determines if the given class has zero-argument .data() and .size() methods
// whose return values are convertible to T* and size_t, respectively.
template <typename DS, typename T>
class HasDataAndSize {
 private:
  template <
      typename C,
      typename std::enable_if<
          std::is_convertible<decltype(std::declval<C>().data()), T*>::value &&
          std::is_convertible<decltype(std::declval<C>().size()),
                              std::size_t>::value>::type* = nullptr>
  static int Test(int);

  template <typename>
  static char Test(...);

 public:
  static constexpr bool value = std::is_same<decltype(Test<DS>(0)), int>::value;
};

namespace test_has_data_and_size {

template <typename DR, typename SR>
struct Test1 {
  DR data();
  SR size();
};
static_assert(HasDataAndSize<Test1<int*, int>, int>::value, "");
static_assert(HasDataAndSize<Test1<int*, int>, const int>::value, "");
static_assert(HasDataAndSize<Test1<const int*, int>, const int>::value, "");
static_assert(!HasDataAndSize<Test1<const int*, int>, int>::value,
              "implicit cast of const int* to int*");
static_assert(!HasDataAndSize<Test1<char*, size_t>, int>::value,
              "implicit cast of char* to int*");

struct Test2 {
  int* data;
  size_t size;
};
static_assert(!HasDataAndSize<Test2, int>::value,
              ".data and .size aren't functions");

struct Test3 {
  int* data();
};
static_assert(!HasDataAndSize<Test3, int>::value, ".size() is missing");

class Test4 {
  int* data();
  size_t size();
};
static_assert(!HasDataAndSize<Test4, int>::value,
              ".data() and .size() are private");

}  // namespace test_has_data_and_size

namespace type_traits_impl {

// Determines if the given type is an enum that converts implicitly to
// an integral type.
template <typename T>
struct IsIntEnum {
 private:
  // This overload is used if the type is an enum, and unary plus
  // compiles and turns it into an integral type.
  template <typename X,
            typename std::enable_if<
                std::is_enum<X>::value &&
                std::is_integral<decltype(+std::declval<X>())>::value>::type* =
                nullptr>
  static int Test(int);

  // Otherwise, this overload is used.
  template <typename>
  static char Test(...);

 public:
  static constexpr bool value =
      std::is_same<decltype(Test<typename std::remove_reference<T>::type>(0)),
                   int>::value;
};

}  // namespace type_traits_impl

// Determines if the given type is integral, or an enum that
// converts implicitly to an integral type.
template <typename T>
struct IsIntlike {
 private:
  using X = typename std::remove_reference<T>::type;

 public:
  static constexpr bool value =
      std::is_integral<X>::value || type_traits_impl::IsIntEnum<X>::value;
};

namespace test_enum_intlike {

enum E1 { e1 };
enum { e2 };
enum class E3 { e3 };
struct S {};

static_assert(type_traits_impl::IsIntEnum<E1>::value, "");
static_assert(type_traits_impl::IsIntEnum<decltype(e2)>::value, "");
static_assert(!type_traits_impl::IsIntEnum<E3>::value, "");
static_assert(!type_traits_impl::IsIntEnum<int>::value, "");
static_assert(!type_traits_impl::IsIntEnum<float>::value, "");
static_assert(!type_traits_impl::IsIntEnum<S>::value, "");

static_assert(IsIntlike<E1>::value, "");
static_assert(IsIntlike<decltype(e2)>::value, "");
static_assert(!IsIntlike<E3>::value, "");
static_assert(IsIntlike<int>::value, "");
static_assert(!IsIntlike<float>::value, "");
static_assert(!IsIntlike<S>::value, "");

}  // namespace test_enum_intlike

}  // namespace rtc

#endif  // RTC_BASE_TYPE_TRAITS_H_
