You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.9 KiB

10 months ago
  1. // Copyright Toru Niina 2019.
  2. // Distributed under the MIT License.
  3. #ifndef TOML11_LITERAL_HPP
  4. #define TOML11_LITERAL_HPP
  5. #include "parser.hpp"
  6. namespace toml
  7. {
  8. inline namespace literals
  9. {
  10. inline namespace toml_literals
  11. {
  12. // implementation
  13. inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
  14. literal_internal_impl(::toml::detail::location loc)
  15. {
  16. using value_type = ::toml::basic_value<
  17. TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>;
  18. // if there are some comments or empty lines, skip them.
  19. using skip_line = ::toml::detail::repeat<toml::detail::sequence<
  20. ::toml::detail::maybe<::toml::detail::lex_ws>,
  21. ::toml::detail::maybe<::toml::detail::lex_comment>,
  22. ::toml::detail::lex_newline
  23. >, ::toml::detail::at_least<1>>;
  24. skip_line::invoke(loc);
  25. // if there are some whitespaces before a value, skip them.
  26. using skip_ws = ::toml::detail::repeat<
  27. ::toml::detail::lex_ws, ::toml::detail::at_least<1>>;
  28. skip_ws::invoke(loc);
  29. // to distinguish arrays and tables, first check it is a table or not.
  30. //
  31. // "[1,2,3]"_toml; // this is an array
  32. // "[table]"_toml; // a table that has an empty table named "table" inside.
  33. // "[[1,2,3]]"_toml; // this is an array of arrays
  34. // "[[table]]"_toml; // this is a table that has an array of tables inside.
  35. //
  36. // "[[1]]"_toml; // this can be both... (currently it becomes a table)
  37. // "1 = [{}]"_toml; // this is a table that has an array of table named 1.
  38. // "[[1,]]"_toml; // this is an array of arrays.
  39. // "[[1],]"_toml; // this also.
  40. const auto the_front = loc.iter();
  41. const bool is_table_key = ::toml::detail::lex_std_table::invoke(loc);
  42. loc.reset(the_front);
  43. const bool is_aots_key = ::toml::detail::lex_array_table::invoke(loc);
  44. loc.reset(the_front);
  45. // If it is neither a table-key or a array-of-table-key, it may be a value.
  46. if(!is_table_key && !is_aots_key)
  47. {
  48. if(auto data = ::toml::detail::parse_value<value_type>(loc, 0))
  49. {
  50. return data.unwrap();
  51. }
  52. }
  53. // Note that still it can be a table, because the literal might be something
  54. // like the following.
  55. // ```cpp
  56. // R"( // c++11 raw string literals
  57. // key = "value"
  58. // int = 42
  59. // )"_toml;
  60. // ```
  61. // It is a valid toml file.
  62. // It should be parsed as if we parse a file with this content.
  63. if(auto data = ::toml::detail::parse_toml_file<value_type>(loc))
  64. {
  65. return data.unwrap();
  66. }
  67. else // none of them.
  68. {
  69. throw ::toml::syntax_error(data.unwrap_err(), source_location(loc));
  70. }
  71. }
  72. inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
  73. operator"" _toml(const char* str, std::size_t len)
  74. {
  75. ::toml::detail::location loc(
  76. std::string("TOML literal encoded in a C++ code"),
  77. std::vector<char>(str, str + len));
  78. // literal length does not include the null character at the end.
  79. return literal_internal_impl(std::move(loc));
  80. }
  81. // value of __cplusplus in C++2a/20 mode is not fixed yet along compilers.
  82. // So here we use the feature test macro for `char8_t` itself.
  83. #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
  84. // value of u8"" literal has been changed from char to char8_t and char8_t is
  85. // NOT compatible to char
  86. inline ::toml::basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>
  87. operator"" _toml(const char8_t* str, std::size_t len)
  88. {
  89. ::toml::detail::location loc(
  90. std::string("TOML literal encoded in a C++ code"),
  91. std::vector<char>(reinterpret_cast<const char*>(str),
  92. reinterpret_cast<const char*>(str) + len));
  93. return literal_internal_impl(std::move(loc));
  94. }
  95. #endif
  96. } // toml_literals
  97. } // literals
  98. } // toml
  99. #endif//TOML11_LITERAL_HPP