default_constructible_unary_fn.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2014. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED
  11. #define BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED
  12. #include <boost/optional/optional.hpp>
  13. #include <boost/mpl/if.hpp>
  14. #include <boost/type_traits/has_trivial_constructor.hpp>
  15. namespace boost
  16. {
  17. namespace range_detail
  18. {
  19. template<typename F, typename R>
  20. class default_constructible_unary_fn_wrapper
  21. {
  22. public:
  23. typedef R result_type;
  24. default_constructible_unary_fn_wrapper()
  25. {
  26. }
  27. default_constructible_unary_fn_wrapper(const F& source)
  28. : m_impl(source)
  29. {
  30. }
  31. default_constructible_unary_fn_wrapper(const default_constructible_unary_fn_wrapper& source)
  32. : m_impl(source.m_impl)
  33. {
  34. }
  35. default_constructible_unary_fn_wrapper& operator=(const default_constructible_unary_fn_wrapper& source)
  36. {
  37. if (source.m_impl)
  38. {
  39. // Lambda are not copy/move assignable.
  40. m_impl.emplace(*source.m_impl);
  41. }
  42. else
  43. {
  44. m_impl.reset();
  45. }
  46. return *this;
  47. }
  48. template<typename Arg>
  49. R operator()(const Arg& arg) const
  50. {
  51. BOOST_ASSERT(m_impl);
  52. return (*m_impl)(arg);
  53. }
  54. template<typename Arg>
  55. R operator()(Arg& arg) const
  56. {
  57. BOOST_ASSERT(m_impl);
  58. return (*m_impl)(arg);
  59. }
  60. private:
  61. boost::optional<F> m_impl;
  62. };
  63. template<typename F, typename R>
  64. struct default_constructible_unary_fn_gen
  65. {
  66. typedef typename boost::mpl::if_<
  67. boost::has_trivial_default_constructor<F>,
  68. F,
  69. default_constructible_unary_fn_wrapper<F,R>
  70. >::type type;
  71. };
  72. } // namespace range_detail
  73. } // namespace boost
  74. #endif // include guard