decay.hpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /*!
  2. @file
  3. Defines a replacement for `std::decay`, which is sometimes too slow at
  4. compile-time.
  5. @copyright Louis Dionne 2013-2017
  6. Distributed under the Boost Software License, Version 1.0.
  7. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  8. */
  9. #ifndef BOOST_HANA_DETAIL_DECAY_HPP
  10. #define BOOST_HANA_DETAIL_DECAY_HPP
  11. #include <boost/hana/config.hpp>
  12. #include <type_traits>
  13. BOOST_HANA_NAMESPACE_BEGIN namespace detail {
  14. //! @ingroup group-details
  15. //! Equivalent to `std::decay`, except faster.
  16. //!
  17. //! `std::decay` in libc++ is implemented in a suboptimal way. Since
  18. //! this is used literally everywhere by the `make<...>` functions, it
  19. //! is very important to keep this as efficient as possible.
  20. //!
  21. //! @note
  22. //! `std::decay` is still being used in some places in the library.
  23. //! Indeed, this is a peephole optimization and it would not be wise
  24. //! to clutter the code with our own implementation of `std::decay`,
  25. //! except when this actually makes a difference in compile-times.
  26. template <typename T, typename U = typename std::remove_reference<T>::type>
  27. struct decay {
  28. using type = typename std::remove_cv<U>::type;
  29. };
  30. template <typename T, typename U>
  31. struct decay<T, U[]> { using type = U*; };
  32. template <typename T, typename U, std::size_t N>
  33. struct decay<T, U[N]> { using type = U*; };
  34. template <typename T, typename R, typename ...A>
  35. struct decay<T, R(A...)> { using type = R(*)(A...); };
  36. template <typename T, typename R, typename ...A>
  37. struct decay<T, R(A..., ...)> { using type = R(*)(A..., ...); };
  38. } BOOST_HANA_NAMESPACE_END
  39. #endif // !BOOST_HANA_DETAIL_DECAY_HPP