string.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*!
  2. @file
  3. Forward declares `boost::hana::string`.
  4. @copyright Louis Dionne 2013-2016
  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_STRING_HPP
  9. #define BOOST_HANA_FWD_STRING_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/fwd/core/make.hpp>
  12. BOOST_HANA_NAMESPACE_BEGIN
  13. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  14. //! @ingroup group-datatypes
  15. //! Compile-time string.
  16. //!
  17. //! Conceptually, a `hana::string` is like a tuple holding
  18. //! `integral_constant`s of underlying type `char`. However, the
  19. //! interface of `hana::string` is not as rich as that of a tuple,
  20. //! because a string can only hold compile-time characters as opposed
  21. //! to any kind of object.
  22. //!
  23. //! Compile-time strings are used for simple purposes like being keys in a
  24. //! `hana::map` or tagging the members of a `Struct`. However, you might
  25. //! find that `hana::string` does not provide enough functionality to be
  26. //! used as a full-blown compile-time string implementation (e.g. regexp
  27. //! matching or substring finding). Indeed, providing a comprehensive
  28. //! string interface is a lot of job, and it is out of the scope of the
  29. //! library for the time being.
  30. //!
  31. //!
  32. //! @note
  33. //! The representation of `hana::string` is implementation-defined.
  34. //! In particular, one should not take for granted that the template
  35. //! parameters are `char`s. The proper way to access the contents of
  36. //! a `hana::string` as character constants is to use `hana::unpack`
  37. //! or `hana::to<char const*>`, as documented below.
  38. //!
  39. //!
  40. //! Modeled concepts
  41. //! ----------------
  42. //! For most purposes, a `hana::string` is functionally equivalent to a
  43. //! tuple holding `Constant`s of underlying type `char`.
  44. //!
  45. //! 1. `Comparable`\n
  46. //! Two strings are equal if and only if they have the same number of
  47. //! characters and characters at corresponding indices are equal.
  48. //! @include example/string/comparable.cpp
  49. //!
  50. //! 2. `Orderable`\n
  51. //! The total order implemented for `Orderable` is the usual
  52. //! lexicographical comparison of strings.
  53. //! @include example/string/orderable.cpp
  54. //!
  55. //! 3. `Foldable`\n
  56. //! Folding a string is equivalent to folding the sequence of its
  57. //! characters.
  58. //! @include example/string/foldable.cpp
  59. //!
  60. //! 4. `Iterable`\n
  61. //! Iterating over a string is equivalent to iterating over the sequence
  62. //! of its characters. Also note that `operator[]` can be used instead of
  63. //! the `at` function.
  64. //! @include example/string/iterable.cpp
  65. //!
  66. //! 5. `Searchable`\n
  67. //! Searching through a string is equivalent to searching through the
  68. //! sequence of its characters.
  69. //! @include example/string/searchable.cpp
  70. //!
  71. //! 6. `Hashable`\n
  72. //! The hash of a compile-time string is a type uniquely representing
  73. //! that string.
  74. //! @include example/string/hashable.cpp
  75. //!
  76. //!
  77. //! Conversion to `char const*`
  78. //! ---------------------------
  79. //! A `hana::string` can be converted to a `constexpr` null-delimited
  80. //! string of type `char const*` by using `to<char const*>`. This makes
  81. //! it easy to turn a compile-time string into a runtime string. However,
  82. //! note that this conversion is not an embedding, because `char const*`
  83. //! does not model the same concepts as `hana::string` does.
  84. //! @include example/string/to.cpp
  85. //!
  86. //!
  87. //! > #### Rationale for `hana::string` not being a `Constant`
  88. //! > The underlying type held by a `hana::string` could be either
  89. //! > `char const*` or some other constexpr-enabled string-like container.
  90. //! > In the first case, `hana::string` can not be a `Constant` because
  91. //! > the models of several concepts would not be respected by the
  92. //! > underlying type, causing `value` not to be structure-preserving.
  93. //! > Providing an underlying value of constexpr-enabled string-like
  94. //! > container type like `std::string_view` would be great, but that's
  95. //! > a bit complicated for the time being.
  96. template <typename implementation_defined>
  97. struct string {
  98. //! Equivalent to `hana::equal`
  99. template <typename X, typename Y>
  100. friend constexpr auto operator==(X&& x, Y&& y);
  101. //! Equivalent to `hana::not_equal`
  102. template <typename X, typename Y>
  103. friend constexpr auto operator!=(X&& x, Y&& y);
  104. //! Equivalent to `hana::less`
  105. template <typename X, typename Y>
  106. friend constexpr auto operator<(X&& x, Y&& y);
  107. //! Equivalent to `hana::greater`
  108. template <typename X, typename Y>
  109. friend constexpr auto operator>(X&& x, Y&& y);
  110. //! Equivalent to `hana::less_equal`
  111. template <typename X, typename Y>
  112. friend constexpr auto operator<=(X&& x, Y&& y);
  113. //! Equivalent to `hana::greater_equal`
  114. template <typename X, typename Y>
  115. friend constexpr auto operator>=(X&& x, Y&& y);
  116. //! Equivalent to `hana::at`
  117. template <typename N>
  118. constexpr decltype(auto) operator[](N&& n);
  119. };
  120. #else
  121. template <char ...s>
  122. struct string;
  123. #endif
  124. //! Tag representing a compile-time string.
  125. //! @relates hana::string
  126. struct string_tag { };
  127. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  128. //! Create a compile-time `hana::string` from a parameter pack of `char`
  129. //! `integral_constant`s.
  130. //! @relates hana::string
  131. //!
  132. //! Given zero or more `integral_constant`s of underlying type `char`,
  133. //! `make<string_tag>` creates a `hana::string` containing those characters.
  134. //! This is provided mostly for consistency with the rest of the library,
  135. //! as `hana::string_c` is more convenient to use in most cases.
  136. //!
  137. //!
  138. //! Example
  139. //! -------
  140. //! @include example/string/make.cpp
  141. template <>
  142. constexpr auto make<string_tag> = [](auto&& ...chars) {
  143. return string<implementation_defined>{};
  144. };
  145. #endif
  146. //! Alias to `make<string_tag>`; provided for convenience.
  147. //! @relates hana::string
  148. constexpr auto make_string = make<string_tag>;
  149. //! Create a compile-time string from a parameter pack of characters.
  150. //! @relates hana::string
  151. //!
  152. //!
  153. //! Example
  154. //! -------
  155. //! @include example/string/string_c.cpp
  156. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  157. template <char ...s>
  158. constexpr string<implementation_defined> string_c{};
  159. #else
  160. template <char ...s>
  161. constexpr string<s...> string_c{};
  162. #endif
  163. //! Create a compile-time string from a string literal.
  164. //! @relates hana::string
  165. //!
  166. //! This macro is a more convenient alternative to `string_c` for creating
  167. //! compile-time strings. However, since this macro uses a lambda
  168. //! internally, it can't be used in an unevaluated context.
  169. //!
  170. //!
  171. //! Example
  172. //! -------
  173. //! @include example/string/macro.cpp
  174. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  175. auto BOOST_HANA_STRING(s) = see documentation;
  176. #define BOOST_HANA_STRING(s) see documentation
  177. // Note:
  178. // The trick above seems to exploit a bug in Doxygen, which makes the
  179. // BOOST_HANA_STRING macro appear in the related objects of hana::string
  180. // (as we want it to).
  181. #else
  182. // defined in <boost/hana/string.hpp>
  183. #endif
  184. #ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
  185. namespace literals {
  186. //! Creates a compile-time string from a string literal.
  187. //! @relatesalso boost::hana::string
  188. //!
  189. //! The string literal is parsed at compile-time and the result is
  190. //! returned as a `hana::string`. This feature is an extension that
  191. //! is disabled by default; see below for details.
  192. //!
  193. //! @note
  194. //! Only narrow string literals are supported right now; support for
  195. //! fancier types of string literals like wide or UTF-XX might be
  196. //! added in the future if there is a demand for it. See [this issue]
  197. //! [Hana.issue80] if you need this.
  198. //!
  199. //! @warning
  200. //! This user-defined literal is an extension which requires a special
  201. //! string literal operator that is not part of the standard yet.
  202. //! That operator is supported by both Clang and GCC, and several
  203. //! proposals were made for it to enter C++17. However, since it is
  204. //! not standard, it is disabled by default and defining the
  205. //! `BOOST_HANA_CONFIG_ENABLE_STRING_UDL` config macro is required
  206. //! to get this operator. Hence, if you want to stay safe, just use
  207. //! the `BOOST_HANA_STRING` macro instead. If you want to be fast and
  208. //! furious (I do), define `BOOST_HANA_CONFIG_ENABLE_STRING_UDL`.
  209. //!
  210. //!
  211. //! Example
  212. //! -------
  213. //! @include example/string/literal.cpp
  214. //!
  215. //! [Hana.issue80]: https://github.com/boostorg/hana/issues/80
  216. template <typename CharT, CharT ...s>
  217. constexpr auto operator"" _s();
  218. }
  219. #endif
  220. BOOST_HANA_NAMESPACE_END
  221. #endif // !BOOST_HANA_FWD_STRING_HPP