Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / libc++ / trunk / test / utilities / tuple / tuple.tuple / tuple.cnstr / const_Types.pass.cpp
index 04cb3d5..ca53cd3 100644 (file)
 #include <string>
 #include <cassert>
 
+
+template <class ...>
+struct never {
+    enum { value = 0 };
+};
+
+struct NoValueCtor
+{
+    NoValueCtor() : id(++count) {}
+    NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
+
+    // The constexpr is required to make is_constructible instantiate this template.
+    // The explicit is needed to test-around a similar bug with is_convertible.
+    template <class T>
+    constexpr explicit NoValueCtor(T)
+    { static_assert(never<T>::value, "This should not be instantiated"); }
+
+    static int count;
+    int id;
+};
+
+int NoValueCtor::count = 0;
+
+
+struct NoValueCtorEmpty
+{
+    NoValueCtorEmpty() {}
+    NoValueCtorEmpty(NoValueCtorEmpty const &) {}
+
+    template <class T>
+    constexpr explicit NoValueCtorEmpty(T)
+    { static_assert(never<T>::value, "This should not be instantiated"); }
+};
+
 int main()
 {
     {
@@ -56,6 +90,23 @@ int main()
         assert(std::get<1>(t) == nullptr);
         assert(std::get<2>(t) == "text");
     }
+    // __tuple_leaf<T> uses is_constructible<T, U> to disable its explicit converting
+    // constructor overload __tuple_leaf(U &&). Evaluating is_constructible can cause a compile error.
+    // This overload is evaluated when __tuple_leafs copy or move ctor is called.
+    // This checks that is_constructible is not evaluated when U == __tuple_leaf.
+    {
+        std::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
+        assert(std::get<0>(t) == 1);
+        assert(std::get<1>(t).id == 1);
+        assert(std::get<2>(t) == 2);
+        assert(std::get<3>(t) == 3);
+    }
+    {
+        std::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
+        assert(std::get<0>(t) == 1);
+        assert(std::get<2>(t) == 2);
+        assert(std::get<3>(t) == 3);
+    }
     // extensions
     {
         std::tuple<int, char*, std::string> t(2);