text: //===----------------------------------------------------------------------===//
  //
  // 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
  //
  //===----------------------------------------------------------------------===//
  
  // UNSUPPORTED: c++03
  
  // <filesystem>
  
  // template <class Tp> struct __is_pathable
  
  // [path.req]
  // In addition to the requirements (5), function template parameters named
  // `Source` shall be one of:
  // * basic_string<_ECharT, _Traits, _Alloc>
  // * InputIterator with a value_type of _ECharT
  // * A character array, which points to a NTCTS after array-to-pointer decay.
  
  
  #include "filesystem_include.h"
  #include <type_traits>
  #include <cassert>
  
  #include "test_macros.h"
  #include "test_iterators.h"
  #include "min_allocator.h"
  #include "constexpr_char_traits.h"
  
  using fs::__is_pathable;
  
  template <class Tp>
  struct Identity { typedef Tp type; };
  
  template <class Source>
  Identity<Source> CheckSourceType(Source const&);
  
  template <class Tp>
  using GetSourceType = typename decltype(CheckSourceType(std::declval<Tp>()))::type;
  
  template <class Tp, class Exp,
            class ExpQual = typename std::remove_const<Exp>::type>
  using CheckPass = std::is_same<ExpQual, GetSourceType<Tp>>;
  
  template <class Source>
  using CheckPassSource = std::integral_constant<bool,
          CheckPass<Source&,        Source>::value &&
          CheckPass<Source const&,  Source>::value &&
          CheckPass<Source&&,       Source>::value &&
          CheckPass<Source const&&, Source>::value
    >;
  
  template <class CharT>
  struct MakeTestType {
    using value_type = CharT;
    using string_type = std::basic_string<CharT>;
    using string_type2 = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
    using string_view_type = std::basic_string_view<CharT>;
    using string_view_type2 = std::basic_string_view<CharT, constexpr_char_traits<CharT>>;
    using cstr_type = CharT* const;
    using const_cstr_type = const CharT*;
    using array_type = CharT[25];
    using const_array_type = const CharT[25];
    using iter_type = cpp17_input_iterator<CharT*>;
    using bad_iter_type = cpp17_input_iterator<signed char*>;
  
    template <class TestT>
    static void AssertPathable() {
      static_assert(__is_pathable<TestT>::value, "");
      static_assert(CheckPassSource<TestT>::value, "cannot pass as Source const&");
      ASSERT_SAME_TYPE(CharT, typename __is_pathable<TestT>::__char_type);
    }
  
    template <class TestT>
    static void AssertNotPathable() {
      static_assert(!__is_pathable<TestT>::value, "");
    }
  
    static void Test() {
      AssertPathable<string_type>();
      AssertPathable<string_type2>();
      AssertPathable<string_view_type>();
      AssertPathable<string_view_type2>();
      AssertPathable<cstr_type>();
      AssertPathable<const_cstr_type>();
      AssertPathable<array_type>();
      AssertPathable<const_array_type>();
      AssertPathable<iter_type>();
  
      AssertNotPathable<CharT>();
      AssertNotPathable<bad_iter_type>();
      AssertNotPathable<signed char*>();
    }
  };
  
  int main(int, char**) {
    MakeTestType<char>::Test();
  #ifndef TEST_HAS_NO_WIDE_CHARACTERS
    MakeTestType<wchar_t>::Test();
  #endif
    MakeTestType<char16_t>::Test();
    MakeTestType<char32_t>::Test();
  
    return 0;
  }
  