forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is dual licensed under the MIT and the University of Illinois Open
 | 
						|
// Source Licenses. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
// UNSUPPORTED: c++98, c++03, c++11, c++14
 | 
						|
 | 
						|
// <utility>
 | 
						|
 | 
						|
// struct in_place_tag { in_place_tag() = delete; };
 | 
						|
//
 | 
						|
// using in_place_t = in_place_tag(&)(unspecified);
 | 
						|
// template <class T>
 | 
						|
//     using in_place_type_t = in_place_tag(&)(unspecified<T>);
 | 
						|
// template <size_t N>
 | 
						|
//     using in_place_index_t = in_place_tag(&)(unspecified<N>);
 | 
						|
//
 | 
						|
// in_place_tag in_place(unspecified);
 | 
						|
//
 | 
						|
// template <class T>;
 | 
						|
// in_place_tag in_place(unspecified<T>);
 | 
						|
//
 | 
						|
// template <size_t N>
 | 
						|
// in_place_tag in_place(unspecified<N>);
 | 
						|
 | 
						|
#include <utility>
 | 
						|
#include <cassert>
 | 
						|
#include <memory>
 | 
						|
 | 
						|
#include "test_macros.h"
 | 
						|
#include "type_id.h"
 | 
						|
 | 
						|
template <class Tp>
 | 
						|
struct CheckRet : std::false_type {};
 | 
						|
template <class Arg>
 | 
						|
struct CheckRet<std::in_place_tag(Arg)> : std::true_type {};
 | 
						|
 | 
						|
TypeID const* test_fn(std::in_place_t) { return &makeTypeID<std::in_place_t>(); }
 | 
						|
template <class T>
 | 
						|
TypeID const* test_fn(std::in_place_type_t<T>)
 | 
						|
{ return &makeTypeID<std::in_place_type_t<T>>(); }
 | 
						|
 | 
						|
template <size_t I>
 | 
						|
TypeID const* test_fn(std::in_place_index_t<I>)
 | 
						|
{ return &makeTypeID<std::in_place_index_t<I>>(); }
 | 
						|
 | 
						|
// Concrete test overloads that don't have to be deduced.
 | 
						|
template <class Tag>
 | 
						|
TypeID const* concrete_test_fn(Tag) {  return &makeTypeID<Tag>(); }
 | 
						|
 | 
						|
template <class Tp>
 | 
						|
bool check_tag_basic() {
 | 
						|
  using RawTp = typename std::remove_reference<Tp>::type;
 | 
						|
  static_assert(std::is_lvalue_reference<Tp>::value, "");
 | 
						|
  static_assert(std::is_function<RawTp>::value, "");
 | 
						|
  static_assert(CheckRet<RawTp>::value, "");
 | 
						|
  auto concrete_fn = concrete_test_fn<Tp>;
 | 
						|
  return test_fn((Tp)std::in_place) == &makeTypeID<Tp>()
 | 
						|
      && concrete_fn(std::in_place) == &makeTypeID<Tp>();
 | 
						|
}
 | 
						|
 | 
						|
int main() {
 | 
						|
    // test in_place_tag
 | 
						|
    {
 | 
						|
        static_assert(!std::is_default_constructible<std::in_place_tag>::value, "");
 | 
						|
    }
 | 
						|
    // test in_place_t
 | 
						|
    {
 | 
						|
        using T = std::in_place_t;
 | 
						|
        assert(check_tag_basic<std::in_place_t>());
 | 
						|
        assert(test_fn((T)std::in_place) == &makeTypeID<T>());
 | 
						|
    }
 | 
						|
    // test in_place_type_t
 | 
						|
    {
 | 
						|
        using T1 = std::in_place_type_t<void>;
 | 
						|
        using T2 = std::in_place_type_t<int>;
 | 
						|
        using T3 = std::in_place_type_t<const int>;
 | 
						|
        assert(check_tag_basic<T1>());
 | 
						|
        assert(check_tag_basic<T2>());
 | 
						|
        assert(check_tag_basic<T3>());
 | 
						|
        static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
 | 
						|
        static_assert(!std::is_same<T2, T3>::value, "");
 | 
						|
    }
 | 
						|
    // test in_place_index_t
 | 
						|
    {
 | 
						|
        using T1 = std::in_place_index_t<0>;
 | 
						|
        using T2 = std::in_place_index_t<1>;
 | 
						|
        using T3 = std::in_place_index_t<static_cast<size_t>(-1)>;
 | 
						|
        assert(check_tag_basic<T1>());
 | 
						|
        assert(check_tag_basic<T2>());
 | 
						|
        assert(check_tag_basic<T3>());
 | 
						|
        static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
 | 
						|
        static_assert(!std::is_same<T2, T3>::value, "");
 | 
						|
    }
 | 
						|
} |