Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions doc/conversion.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,17 @@ This includes C++ built-in pointers, `std::shared_ptr`,
// Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
// Returns: dynamic_cast<Derived>(x)
template <class Derived, class Base>
inline Derived polymorphic_cast(Base* x);
constexpr Derived polymorphic_cast(Base* x);

// Effects: assert( dynamic_cast<Derived>(x) == x );
// Returns: static_cast<Derived>(x)
template <class Derived, class Base>
inline Derived polymorphic_downcast(Base* x);
constexpr Derived polymorphic_downcast(Base* x);

// Effects: assert( dynamic_cast<Derived>(&x) == &x );
// Returns: static_cast<Derived>(x)
template <class Derived, class Base>
inline Derived polymorphic_downcast(Base& x);
constexpr Derived polymorphic_downcast(Base& x);

// Throws: std::bad_cast if ( dynamic_pointer_cast<Derived>(x) == 0 )
// Returns: dynamic_pointer_cast<Derived>(x)
Expand Down
14 changes: 11 additions & 3 deletions include/boost/polymorphic_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
# include <typeinfo>
# include <type_traits>

#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST constexpr
#else
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST inline
#endif

namespace boost
{
// See the documentation for descriptions of how to choose between
Expand All @@ -74,7 +80,7 @@ namespace boost
// section 15.8 exercise 1, page 425.

template <class Target, class Source>
inline Target polymorphic_cast(Source* x)
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST Target polymorphic_cast(Source* x)
{
Target tmp = dynamic_cast<Target>(x);
if ( tmp == 0 ) boost::throw_exception( std::bad_cast() );
Expand All @@ -93,7 +99,7 @@ namespace boost
// Contributed by Dave Abrahams

template <class Target, class Source>
inline Target polymorphic_downcast(Source* x)
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST Target polymorphic_downcast(Source* x)
{
BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
return static_cast<Target>(x);
Expand All @@ -109,7 +115,7 @@ namespace boost
// Contributed by Julien Delacroix

template <class Target, class Source>
inline typename std::enable_if<
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST typename std::enable_if<
std::is_reference<Target>::value, Target
>::type polymorphic_downcast(Source& x)
{
Expand All @@ -121,4 +127,6 @@ namespace boost

} // namespace boost

#undef BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST

#endif // BOOST_POLYMORPHIC_CAST_HPP
42 changes: 42 additions & 0 deletions test/cast_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,48 @@ namespace
};
}

constexpr bool compile_time_polymorphic_cast_check() {
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
Derived derived;
Base* base = &derived;
return polymorphic_cast<Derived*>(base) != nullptr;
#endif
return true;
}

static_assert(
compile_time_polymorphic_cast_check(),
"polymorphic_cast does not work at compile time"
);

constexpr bool compile_time_polymorphic_downcast_check() {
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
Derived derived;
Base* base = &derived;
return polymorphic_downcast<Derived*>(base) != nullptr;
#endif
return true;
}

static_assert(
compile_time_polymorphic_downcast_check(),
"polymorphic_downcast does not work at compile time"
);

constexpr bool compile_time_polymorphic_downcast2_check() {
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
Derived derived;
Base& base = derived;
Derived& derived_again = polymorphic_downcast<Derived&>(base);
(void)derived_again;
#endif
return true;
}

static_assert(
compile_time_polymorphic_downcast2_check(),
"polymorphic_downcast does not work at compile time"
);

int main( int argc, char * argv[] )
{
Expand Down
Loading