message: elle.cast: Add plain pointers and reference cast.
diff: @@ -7,6 +7,28 @@ namespace elle
  template <typename T>
  struct cast
  {
  + /// Cast \a p to type \a T.
  + template <typename U>
  + static T*
  + runtime(U* p)
  + {
  + return dynamic_cast<T*>(p);
  + }
  +
  + /// Cast \a p to type \a T.
  + ///
  + /// \throws elle::Error if the cast is not possible.
  + template <typename U>
  + static T&
  + runtime(U& p)
  + {
  + if (auto res = runtime(&p))
  + return *res;
  + else
  + elle::err("{} is not of type {}",
  + elle::type_info(p), elle::type_info<T>());
  + }
  +
  /// Cast \a p to type \a T.
  ///
  /// If the cast is possible, the new pointer is returned and \a p is
  @@ -15,12 +37,14 @@ namespace elle
  static std::unique_ptr<T>
  runtime(std::unique_ptr<U>& p)
  {
  - T* res = dynamic_cast<T*>(p.get());
  - if (!res)
  - return nullptr;
  + if (T* res = runtime(p.get()))
  + {
  p.release();
  return std::unique_ptr<T>(res);
  }
  + else
  + return nullptr;
  + }
  /// Cast \a p to type \a T.
  ///
  @@ -30,11 +54,27 @@ namespace elle
  static std::unique_ptr<T>
  runtime(std::unique_ptr<U>&& p)
  {
  - T* res = dynamic_cast<T*>(p.get());
  - if (!res)
  - return nullptr;
  - p.release();
  - return std::unique_ptr<T>(res);
  + return runtime(p);
  + }
  +
  + /// Unconditionnaly cast \a p to type \a T.
  + template <typename U>
  + static T*
  + compiletime(U* p)
  + {
  + if constexpr(std::is_polymorphic_v<U>)
  + ELLE_ASSERT(dynamic_cast<T*>(p));
  + return static_cast<T*>(p);
  + }
  +
  + /// Unconditionnaly cast \a p to type \a T.
  + ///
  + /// \throws elle::Error if the cast is not possible.
  + template <typename U>
  + static T&
  + compiletime(U& p)
  + {
  + return *compiletime(&p);
  }
  /// Unconditionnaly cast \a p to type \a T.
  @@ -42,8 +82,7 @@ namespace elle
  static std::unique_ptr<T>
  compiletime(std::unique_ptr<U>& p)
  {
  - ELLE_ASSERT(dynamic_cast<T*>(p.get()));
  - T* res = static_cast<T*>(p.get());
  + T* res = compiletime(p.get());
  p.release();
  return std::unique_ptr<T>(res);
  }
  @@ -53,8 +92,7 @@ namespace elle
  static std::unique_ptr<T>
  compiletime(std::unique_ptr<U>&& p)
  {
  - ELLE_ASSERT(dynamic_cast<T*>(p.get()));
  - T* res = static_cast<T*>(p.get());
  + T* res = compiletime(p.get());
  p.release();
  return std::unique_ptr<T>(res);
  }
  