string.hpp 11 KB

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