make.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*!
  2. @file
  3. Forward declares `boost::hana::make`.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_FWD_CORE_MAKE_HPP
  9. #define BOOST_HANA_FWD_CORE_MAKE_HPP
  10. #include <boost/hana/config.hpp>
  11. BOOST_HANA_NAMESPACE_BEGIN
  12. //! @ingroup group-core
  13. //! Create an object of the given tag with the given arguments.
  14. //!
  15. //! This function serves the same purpose as constructors in usual C++.
  16. //! However, instead of creating an object of a specific C++ type, it
  17. //! creates an object of a specific tag, regardless of the C++ type
  18. //! of that object.
  19. //!
  20. //! This function is actually a variable template, so `make<T>` can be
  21. //! passed around as a function object creating an object of tag `T`.
  22. //! Also, it uses tag-dispatching so this is how it should be customized
  23. //! for user-defined tags.
  24. //!
  25. //! Finally, the default implementation of `make` is equivalent to calling
  26. //! the constructor of the given tag with the corresponding arguments.
  27. //! In other words, by default,
  28. //! @code
  29. //! make<T>(args...) == T(args...)
  30. //! @endcode
  31. //!
  32. //! Note that the arguments are perfectly forwarded and the form of
  33. //! construction which is used is exactly as documented, i.e. `T(args...)`.
  34. //! However, if `T(args...)` is not a valid expression, a compilation
  35. //! error is triggered. This default behavior is useful because it makes
  36. //! foreign C++ types that have no notion of tag constructible with `make`
  37. //! out-of-the-box, since their tag is exactly themselves.
  38. //!
  39. //!
  40. //! Example
  41. //! -------
  42. //! @include example/core/make.cpp
  43. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  44. template <typename Tag>
  45. constexpr auto make = [](auto&& ...x) -> decltype(auto) {
  46. return tag-dispatched;
  47. };
  48. #else
  49. template <typename Tag, typename = void>
  50. struct make_impl;
  51. template <typename Tag>
  52. struct make_t {
  53. template <typename ...X>
  54. constexpr decltype(auto) operator()(X&& ...x) const {
  55. return make_impl<Tag>::apply(static_cast<X&&>(x)...);
  56. }
  57. };
  58. template <typename Tag>
  59. constexpr make_t<Tag> make{};
  60. #endif
  61. BOOST_HANA_NAMESPACE_END
  62. #endif // !BOOST_HANA_FWD_CORE_MAKE_HPP