iterable.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*!
  2. @file
  3. Forward declares `boost::hana::Iterable`.
  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_CONCEPT_ITERABLE_HPP
  9. #define BOOST_HANA_FWD_CONCEPT_ITERABLE_HPP
  10. #include <boost/hana/config.hpp>
  11. BOOST_HANA_NAMESPACE_BEGIN
  12. //! @ingroup group-concepts
  13. //! @defgroup group-Iterable Iterable
  14. //! The `Iterable` concept represents data structures supporting external
  15. //! iteration.
  16. //!
  17. //! Intuitively, an `Iterable` can be seen as a kind of container whose
  18. //! elements can be pulled out one at a time. An `Iterable` also provides
  19. //! a way to know when the _container_ is empty, i.e. when there are no
  20. //! more elements to pull out.
  21. //!
  22. //! Whereas `Foldable` represents data structures supporting internal
  23. //! iteration with the ability to accumulate a result, the `Iterable`
  24. //! concept allows inverting the control of the iteration. This is more
  25. //! flexible than `Foldable`, since it allows iterating over only some
  26. //! part of the structure. This, in turn, allows `Iterable` to work on
  27. //! infinite structures, while trying to fold such a structure would
  28. //! never finish.
  29. //!
  30. //!
  31. //! Minimal complete definition
  32. //! ---------------------------
  33. //! `at`, `drop_front` and `is_empty`
  34. //!
  35. //!
  36. //! @anchor Iterable-lin
  37. //! The linearization of an `Iterable`
  38. //! ----------------------------------
  39. //! Intuitively, for an `Iterable` structure `xs`, the _linearization_ of
  40. //! `xs` is the sequence of all the elements in `xs` as if they had been
  41. //! put in a (possibly infinite) list:
  42. //! @code
  43. //! linearization(xs) = [x1, x2, x3, ...]
  44. //! @endcode
  45. //!
  46. //! The `n`th element of the linearization of an `Iterable` can be
  47. //! accessed with the `at` function. In other words, `at(xs, n) == xn`.
  48. //!
  49. //! Note that this notion is precisely the extension of the [linearization]
  50. //! (@ref Foldable-lin) notion of `Foldable`s to the infinite case. This
  51. //! notion is useful for expressing various properties of `Iterable`s,
  52. //! and is used for that elsewhere in the documentation.
  53. //!
  54. //!
  55. //! Compile-time `Iterable`s
  56. //! ------------------------
  57. //! A _compile-time_ `Iterable` is an `Iterable` for which `is_empty`
  58. //! returns a compile-time `Logical`. These structures allow iteration
  59. //! to be done at compile-time, in the sense that the "loop" doing the
  60. //! iteration can be unrolled because the total length of the structure
  61. //! is kown at compile-time.
  62. //!
  63. //! In particular, note that being a compile-time `Iterable` has nothing
  64. //! to do with being finite or infinite. For example, it would be possible
  65. //! to create a sequence representing the Pythagorean triples as
  66. //! `integral_constant`s. Such a sequence would be infinite, but iteration
  67. //! on the sequence would still be done at compile-time. However, if one
  68. //! tried to iterate over _all_ the elements of the sequence, the compiler
  69. //! would loop indefinitely, in contrast to your program looping
  70. //! indefinitely if the sequence was a runtime one.
  71. //!
  72. //! __In the current version of the library, only compile-time `Iterable`s
  73. //! are supported.__ While it would be possible in theory to support
  74. //! runtime `Iterable`s, doing it efficiently is the subject of some
  75. //! research. In particular, follow [this issue][1] for the current
  76. //! status of runtime `Iterable`s.
  77. //!
  78. //!
  79. //! Laws
  80. //! ----
  81. //! First, we require the equality of two `Iterable`s to be related to the
  82. //! equality of the elements in their linearizations. More specifically,
  83. //! if `xs` and `ys` are two `Iterable`s of data type `It`, then
  84. //! @code
  85. //! xs == ys => at(xs, i) == at(ys, i) for all i
  86. //! @endcode
  87. //!
  88. //! This conveys that two `Iterable`s must have the same linearization
  89. //! in order to be considered equal.
  90. //!
  91. //! Secondly, since every `Iterable` is also a `Searchable`, we require
  92. //! the models of `Iterable` and `Searchable` to be consistent. This is
  93. //! made precise by the following laws. For any `Iterable` `xs` with a
  94. //! linearization of `[x1, x2, x3, ...]`,
  95. //! @code
  96. //! any_of(xs, equal.to(z)) <=> xi == z
  97. //! @endcode
  98. //! for some _finite_ index `i`. Furthermore,
  99. //! @code
  100. //! find_if(xs, pred) == just(the first xi such that pred(xi) is satisfied)
  101. //! @endcode
  102. //! or `nothing` if no such `xi` exists.
  103. //!
  104. //!
  105. //! Refined concepts
  106. //! ----------------
  107. //! 1. `Searchable` (free model)\n
  108. //! Any `Iterable` gives rise to a model of `Searchable`, where the keys
  109. //! and the values are both the elements in the structure. Searching for
  110. //! a key is just doing a linear search through the elements of the
  111. //! structure.
  112. //! @include example/iterable/searchable.cpp
  113. //!
  114. //! 2. `Foldable` for finite `Iterable`s\n
  115. //! Every finite `Iterable` gives rise to a model of `Foldable`. For
  116. //! these models to be consistent, we require the models of both `Foldable`
  117. //! and `Iterable` to have the same linearization.
  118. //!
  119. //! @note
  120. //! As explained above, `Iterable`s are also `Searchable`s and their
  121. //! models have to be consistent. By the laws presented here, it also
  122. //! means that the `Foldable` model for finite `Iterable`s has to be
  123. //! consistent with the `Searchable` model.
  124. //!
  125. //! For convenience, finite `Iterable`s must only provide a definition of
  126. //! `length` to model the `Foldable` concept; defining the more powerful
  127. //! `unpack` or `fold_left` is not necessary (but still possible). The
  128. //! default implementation of `unpack` derived from `Iterable` + `length`
  129. //! uses the fact that `at(xs, i)` denotes the `i`th element of `xs`'s
  130. //! linearization, and that the linearization of a finite `Iterable` must
  131. //! be the same as its linearization as a `Foldable`.
  132. //!
  133. //!
  134. //! Concrete models
  135. //! ---------------
  136. //! `hana::tuple`, `hana::string`, `hana::range`
  137. //!
  138. //!
  139. //! [1]: https://github.com/boostorg/hana/issues/40
  140. template <typename It>
  141. struct Iterable;
  142. BOOST_HANA_NAMESPACE_END
  143. #endif // !BOOST_HANA_FWD_CONCEPT_ITERABLE_HPP