]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Move dynamic_unique_cast to Utilities 6180/head
authorDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Fri, 6 Apr 2018 13:04:38 +0000 (15:04 +0200)
committerDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Fri, 6 Apr 2018 13:21:16 +0000 (15:21 +0200)
doc/news/changes/minor/20180403Bangerth
include/deal.II/base/std_cxx11/unique_ptr.h
include/deal.II/base/utilities.h
source/fe/mapping_q.cc
tests/base/dynamic_unique_cast.cc

index d5828853eae65f5635ab79a1530ec5bd618c55c1..66e1c17e3f02b140844c3f3089685054e746e37f 100644 (file)
@@ -1,5 +1,4 @@
-New: There is now a function dynamic_unique_cast() that does for
-`std::unique_ptr` objects what `dynamic_cast` does for regular
-pointers.
+New: There is now a function Utilities::dynamic_unique_cast() that does for
+`std::unique_ptr` objects what `dynamic_cast` does for regular pointers.
 <br>
 (Wolfgang Bangerth, 2018/04/03)
index 0182927a3e527471eb2538f3a8c8a23417a8bfa9..d99ad5cc68c5c80521c4222177a218886beeac92 100644 (file)
@@ -33,71 +33,4 @@ DEAL_II_NAMESPACE_OPEN
 namespace std_cxx1x = std_cxx11;
 DEAL_II_NAMESPACE_CLOSE
 
-
-DEAL_II_NAMESPACE_OPEN
-
-/**
- * Convert an object of type `std::unique_ptr<From>` to an object of
- * type `std::unique_ptr<To>`, where it is assumed that we can cast
- * the pointer to `From` to a pointer to `To` using a `dynamic_cast`
- * -- in other words, we assume that `From` and `To` are connected
- * through a class hierarchy, and that the object pointed to is in
- * fact of a type that contains both a `From` and a `To`. An example
- * is if either `To` is derived from `From` or the other way around.
- *
- * The function throws an exception of type `std::bad_cast` if the
- * `dynamic_cast` does not succeed. This is the same exception you
- * would get if a regular `dynamic_cast` between object types (but not
- * pointer types) does not succeed.
- *
- * An example of how this function works is as follows:
- * @code
- *   class B { ... };            // A base class. Assume that it has virtual
- *                               // functions so that dynamic_cast can work.
- *   class D : public B { ... }; // A derived class
- *
- *
- *   std::unique_ptr<B> create_object (...) {...}  // A factory function
- *
- *   void foo (...)
- *   {
- *     std::unique_ptr<B> b = create_object (...);
- *
- *     // Assume that we know for some reason that the object above must
- *     // have created a D object but returned it as a std::unique_ptr<B>.
- *     // In order to access the D functionality, we need to cast the
- *     // pointer. Use the equivalent to dynamic_cast:
- *     std::unique_ptr<D> d = dynamic_unique_cast<D>(std::move(b));
- *
- *     // If the object really was a D, then 'd' now points to it. Note
- *     // also that in accordance with the semantics of std::unique_ptr,
- *     // it was necessary to std::move the 'b' object, and indeed 'b'
- *     // now no longer points to anything -- ownership has been
- *     // transferred to 'd'!
- * @endcode
- *
- * @note This function does not try to convert the `Deleter` objects stored
- *   by `std::unique_ptr` objects. The function therefore only works if the
- *   deleter objects are at their defaults, i.e., if they are of type
- *   `std::default_delete<To>` and `std::default_delete<From>`.
- */
-template <typename To, typename From>
-std::unique_ptr<To>
-dynamic_unique_cast (std::unique_ptr<From> &&p)
-{
-  // Let's see if we can cast from 'From' to 'To'. If so, do the cast,
-  // and then release the pointer from the old
-  // owner
-  if (To *cast = dynamic_cast<To *>(p.get()))
-    {
-      std::unique_ptr<To> result(cast);
-      p.release();
-      return result;
-    }
-  else
-    throw std::bad_cast();
-}
-
-DEAL_II_NAMESPACE_CLOSE
-
 #endif
index 69272ecac96fe4058454bac8cfc3c972592968de..051662d6ee5a4e5325e94cfc076503067c8b87c2 100644 (file)
@@ -505,6 +505,68 @@ namespace Utilities
   void unpack (const std::vector<char> &buffer,
                T (&unpacked_object)[N]);
 
+  /**
+   * Convert an object of type `std::unique_ptr<From>` to an object of
+   * type `std::unique_ptr<To>`, where it is assumed that we can cast
+   * the pointer to `From` to a pointer to `To` using a `dynamic_cast`
+   * -- in other words, we assume that `From` and `To` are connected
+   * through a class hierarchy, and that the object pointed to is in
+   * fact of a type that contains both a `From` and a `To`. An example
+   * is if either `To` is derived from `From` or the other way around.
+   *
+   * The function throws an exception of type `std::bad_cast` if the
+   * `dynamic_cast` does not succeed. This is the same exception you
+   * would get if a regular `dynamic_cast` between object types (but not
+   * pointer types) does not succeed.
+   *
+   * An example of how this function works is as follows:
+   * @code
+   *   class B { ... };            // A base class. Assume that it has virtual
+   *                               // functions so that dynamic_cast can work.
+   *   class D : public B { ... }; // A derived class
+   *
+   *
+   *   std::unique_ptr<B> create_object (...) {...}  // A factory function
+   *
+   *   void foo (...)
+   *   {
+   *     std::unique_ptr<B> b = create_object (...);
+   *
+   *     // Assume that we know for some reason that the object above must
+   *     // have created a D object but returned it as a std::unique_ptr<B>.
+   *     // In order to access the D functionality, we need to cast the
+   *     // pointer. Use the equivalent to dynamic_cast:
+   *     std::unique_ptr<D> d = dynamic_unique_cast<D>(std::move(b));
+   *
+   *     // If the object really was a D, then 'd' now points to it. Note
+   *     // also that in accordance with the semantics of std::unique_ptr,
+   *     // it was necessary to std::move the 'b' object, and indeed 'b'
+   *     // now no longer points to anything -- ownership has been
+   *     // transferred to 'd'!
+   * @endcode
+   *
+   * @note This function does not try to convert the `Deleter` objects stored
+   *   by `std::unique_ptr` objects. The function therefore only works if the
+   *   deleter objects are at their defaults, i.e., if they are of type
+   *   `std::default_delete<To>` and `std::default_delete<From>`.
+   */
+  template <typename To, typename From>
+  std::unique_ptr<To>
+  dynamic_unique_cast (std::unique_ptr<From> &&p)
+  {
+    // Let's see if we can cast from 'From' to 'To'. If so, do the cast,
+    // and then release the pointer from the old
+    // owner
+    if (To *cast = dynamic_cast<To *>(p.get()))
+      {
+        std::unique_ptr<To> result(cast);
+        p.release();
+        return result;
+      }
+    else
+      throw std::bad_cast();
+  }
+
   /**
    * A namespace for utility functions that probe system properties.
    *
index 9fd1fbc34a2c2ca87b82f25aca278fdac0f40134..136dc8e7ab2ab7d3ee649cb374175dcb06ad97fb 100644 (file)
@@ -13,7 +13,6 @@
 //
 // ---------------------------------------------------------------------
 
-#include <deal.II/base/std_cxx11/unique_ptr.h>
 #include <deal.II/base/array_view.h>
 #include <deal.II/base/polynomial.h>
 #include <deal.II/base/quadrature.h>
@@ -159,11 +158,11 @@ MappingQ<dim,spacedim>::get_data (const UpdateFlags update_flags,
                                        quadrature);
 
   if (!use_mapping_q_on_all_cells)
-    data->mapping_q1_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+    data->mapping_q1_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                             (std::move(q1_mapping->get_data (update_flags, quadrature)));
 
   // wait for the task above to finish and use returned value
-  data->mapping_qp_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+  data->mapping_qp_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                           (std::move(do_get_data.return_value()));
 
   return std::move(data);
@@ -186,11 +185,11 @@ MappingQ<dim,spacedim>::get_face_data (const UpdateFlags update_flags,
                                        quadrature);
 
   if (!use_mapping_q_on_all_cells)
-    data->mapping_q1_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+    data->mapping_q1_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                             (std::move(q1_mapping->get_face_data (update_flags, quadrature)));
 
   // wait for the task above to finish and use returned value
-  data->mapping_qp_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+  data->mapping_qp_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                           (std::move(do_get_data.return_value()));
   return std::move(data);
 }
@@ -212,11 +211,11 @@ MappingQ<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
                                        quadrature);
 
   if (!use_mapping_q_on_all_cells)
-    data->mapping_q1_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+    data->mapping_q1_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                             (std::move(q1_mapping->get_subface_data (update_flags, quadrature)));
 
   // wait for the task above to finish and use returned value
-  data->mapping_qp_data = dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
+  data->mapping_qp_data = Utilities::dynamic_unique_cast<typename MappingQGeneric<dim,spacedim>::InternalData>
                           (std::move(do_get_data.return_value()));
   return std::move(data);
 }
index 0707a3b9839241b40f8b61cc0dc25bf0b49d892b..ad60c83160f06795cbe35b1c1b58ccbc347dd510 100644 (file)
@@ -18,9 +18,6 @@
 
 #include "../tests.h"
 
-#include <deal.II/base/std_cxx11/unique_ptr.h>
-
-
 class B
 {
 public:
@@ -36,7 +33,7 @@ void test ()
   std::unique_ptr<D> d = std_cxx14::make_unique<D>();
 
   // See that we can successfully downcast to B
-  std::unique_ptr<B> b = dynamic_unique_cast<B>(std::move(d));
+  std::unique_ptr<B> b = Utilities::dynamic_unique_cast<B>(std::move(d));
 
   // Ownership now rests with b, but it's still a D. Verify this:
   Assert (d.get() == nullptr, ExcInternalError());
@@ -44,7 +41,7 @@ void test ()
   Assert (dynamic_cast<D *>(b.get()) != nullptr, ExcInternalError());
 
   // Check that we can again upcast to D:
-  std::unique_ptr<D> dd = dynamic_unique_cast<D>(std::move(b));
+  std::unique_ptr<D> dd = Utilities::dynamic_unique_cast<D>(std::move(b));
 
   // Ownership now rests with b, but it's still a D. Verify this:
   Assert (b.get() == nullptr, ExcInternalError());
@@ -62,7 +59,7 @@ void invalid_test ()
   // Check that we can indeed not upcast to D:
   try
     {
-      std::unique_ptr<D> dd = dynamic_unique_cast<D>(std::move(b));
+      std::unique_ptr<D> dd = Utilities::dynamic_unique_cast<D>(std::move(b));
     }
   catch (const std::bad_cast &)
     {

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.