sum.hpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*!
  2. @file
  3. Forward declares `boost::hana::sum`.
  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_SUM_HPP
  9. #define BOOST_HANA_FWD_SUM_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/core/when.hpp>
  12. #include <boost/hana/fwd/integral_constant.hpp>
  13. BOOST_HANA_NAMESPACE_BEGIN
  14. //! Compute the sum of the numbers of a structure.
  15. //! @ingroup group-Foldable
  16. //!
  17. //! More generally, `sum` will take any foldable structure containing
  18. //! objects forming a Monoid and reduce them using the Monoid's binary
  19. //! operation. The initial state for folding is the identity of the
  20. //! Monoid. It is sometimes necessary to specify the Monoid to use;
  21. //! this is possible by using `sum<M>`. If no Monoid is specified,
  22. //! the structure will use the Monoid formed by the elements it contains
  23. //! (if it knows it), or `integral_constant_tag<int>` otherwise. Hence,
  24. //! @code
  25. //! sum<M>(xs) = fold_left(xs, zero<M or inferred Monoid>(), plus)
  26. //! sum<> = sum<integral_constant_tag<int>>
  27. //! @endcode
  28. //!
  29. //! For numbers, this will just compute the sum of the numbers in the
  30. //! `xs` structure.
  31. //!
  32. //!
  33. //! @note
  34. //! The elements of the structure are not actually required to be in the
  35. //! same Monoid, but it must be possible to perform `plus` on any two
  36. //! adjacent elements of the structure, which requires each pair of
  37. //! adjacent element to at least have a common Monoid embedding. The
  38. //! meaning of "adjacent" as used here is that two elements of the
  39. //! structure `x` and `y` are adjacent if and only if they are adjacent
  40. //! in the linearization of that structure, as documented by the Iterable
  41. //! concept.
  42. //!
  43. //!
  44. //! Why must we sometimes specify the `Monoid` by using `sum<M>`?
  45. //! -------------------------------------------------------------
  46. //! This is because sequence tags like `tuple_tag` are not parameterized
  47. //! (by design). Hence, we do not know what kind of objects are in the
  48. //! sequence, so we can't know a `0` value of which type should be
  49. //! returned when the sequence is empty. Therefore, the type of the
  50. //! `0` to return in the empty case must be specified explicitly. Other
  51. //! foldable structures like `hana::range`s will ignore the suggested
  52. //! Monoid because they know the tag of the objects they contain. This
  53. //! inconsistent behavior is a limitation of the current design with
  54. //! non-parameterized tags, but we have no good solution for now.
  55. //!
  56. //!
  57. //! Example
  58. //! -------
  59. //! @include example/sum.cpp
  60. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  61. constexpr auto sum = see documentation;
  62. #else
  63. template <typename T, typename = void>
  64. struct sum_impl : sum_impl<T, when<true>> { };
  65. template <typename M>
  66. struct sum_t {
  67. template <typename Xs>
  68. constexpr decltype(auto) operator()(Xs&& xs) const;
  69. };
  70. template <typename M = integral_constant_tag<int>>
  71. constexpr sum_t<M> sum{};
  72. #endif
  73. BOOST_HANA_NAMESPACE_END
  74. #endif // !BOOST_HANA_FWD_SUM_HPP