]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / any / misc / any_cast.cc
index ce3f213588960a08ab9703b7514b6924b4cb4f4b..e1b371817e02cbfd57e7974bd049899ffdc28049 100644 (file)
@@ -1,7 +1,6 @@
-// { dg-options "-std=gnu++14" }
-// { dg-do run }
+// { dg-do run { target c++14 } }
 
-// Copyright (C) 2014-2016 Free Software Foundation, Inc.
+// Copyright (C) 2014-2024 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -25,6 +24,7 @@
 
 using std::experimental::any;
 using std::experimental::any_cast;
+using std::experimental::bad_any_cast;
 
 void test01()
 {
@@ -36,7 +36,7 @@ void test01()
   any x(5);                                   // x holds int
   VERIFY(any_cast<int>(x) == 5);              // cast to value
   any_cast<int&>(x) = 10;                     // cast to reference
-  VERIFY(any_cast<int>(x) == 10); 
+  VERIFY(any_cast<int>(x) == 10);
 
   x = "Meow";                                 // x holds const char*
   VERIFY(strcmp(any_cast<const char*>(x), "Meow") == 0);
@@ -45,7 +45,7 @@ void test01()
 
   x = string("Meow");                         // x holds string
   string s, s2("Jane");
-  s = move(any_cast<string&>(x));             // move from any 
+  s = move(any_cast<string&>(x));             // move from any
   VERIFY(s == "Meow");
   any_cast<string&>(x) = move(s2);            // move to any
   VERIFY(any_cast<const string&>(x) == "Jane");
@@ -57,7 +57,6 @@ void test01()
 
 void test02()
 {
-  using std::experimental::bad_any_cast;
   any x(1);
   auto p = any_cast<double>(&x);
   VERIFY(p == nullptr);
@@ -77,8 +76,107 @@ void test02()
   }
 }
 
+static int move_count = 0;
+
+void test03()
+{
+  struct MoveEnabled
+  {
+    MoveEnabled(MoveEnabled&&)
+    {
+      ++move_count;
+    }
+    MoveEnabled() = default;
+    MoveEnabled(const MoveEnabled&) = default;
+  };
+  MoveEnabled m;
+  MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
+  VERIFY(move_count == 1);
+  MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
+  VERIFY(move_count == 1);
+  struct MoveDeleted
+  {
+    MoveDeleted(MoveDeleted&&) = delete;
+    MoveDeleted() = default;
+    MoveDeleted(const MoveDeleted&) = default;
+  };
+  MoveDeleted md;
+  MoveDeleted&& md2 = any_cast<MoveDeleted>(any(std::move(md)));
+  MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
+}
+
+void test05()
+{
+  // PR libstdc++/69321
+  struct noncopyable {
+    noncopyable(noncopyable const&) = delete;
+  };
+
+  any a;
+  auto p = any_cast<noncopyable>(&a);
+  VERIFY( p == nullptr );
+}
+
+void test06()
+{
+  // The contained value of a std::any is always an object type,
+  // but any_cast does not forbid checking for function types.
+
+  any a(1);
+  void (*p1)() = any_cast<void()>(&a);
+  VERIFY( p1 == nullptr );
+  int (*p2)(int) = any_cast<int(int)>(&a);
+  VERIFY( p2 == nullptr );
+  int (*p3)() = any_cast<int()>(&const_cast<const any&>(a));
+  VERIFY( p3 == nullptr );
+
+  try {
+    any_cast<int(&)()>(a);
+    VERIFY( false );
+  } catch (const bad_any_cast&) {
+  }
+
+  try {
+    any_cast<int(&)()>(std::move(a));
+    VERIFY( false );
+  } catch (const bad_any_cast&) {
+  }
+
+  try {
+    any_cast<int(&)()>(const_cast<const any&>(a));
+    VERIFY( false );
+  } catch (const bad_any_cast&) {
+  }
+}
+
+void test07()
+{
+  int arr[3];
+  any a(arr);
+#if __cpp_rtti
+  VERIFY( a.type() == typeid(int*) );  // contained value is decayed
+#endif
+
+  int (*p1)[3] = any_cast<int[3]>(&a);
+#if __cpp_rtti
+  VERIFY( a.type() != typeid(int[3]) ); // so any_cast should return nullptr
+#endif
+  VERIFY( p1 == nullptr );
+  int (*p2)[] = any_cast<int[]>(&a);
+#if __cpp_rtti
+  VERIFY( a.type() != typeid(int[]) ); // so any_cast should return nullptr
+#endif
+  VERIFY( p2 == nullptr );
+  const int (*p3)[] = any_cast<int[]>(&const_cast<const any&>(a));
+  VERIFY( p3 == nullptr );
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
+  test05();
+  test06();
+  test07();
 }