Просмотр исходного кода

Add optional support to cast().
Fix tokenizer to not include an empty trailing object.

Sam Jaffe 4 лет назад
Родитель
Сommit
bf67dbbb07
2 измененных файлов с 21 добавлено и 1 удалено
  1. 17 0
      include/string_utils/cast.h
  2. 4 1
      src/tokenizer.cxx

+ 17 - 0
include/string_utils/cast.h

@@ -9,6 +9,7 @@
 #pragma once
 
 #include <cstdlib>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -49,7 +50,14 @@ struct is_stringy<
 
 namespace string_utils {
 template <typename T> std::pair<T, bool> cast(std::string const & str);
+template <typename T> bool cast(std::string const & str, std::optional<T> & to);
+#if defined(STRING_UTIL_CAST_STD_VARIANT)
+template <typename... Ts>
+bool cast(std::string const & str, std::variant<Ts...> & to);
+#endif
+}
 
+namespace string_utils {
 template <typename T, typename = std::enable_if_t<traits::is_stringy<T>{}>>
 bool cast(std::string const & str, T & to) {
   to = T(str);
@@ -110,6 +118,15 @@ bool cast(std::string const & str, std::variant<Ts...> & to) {
 }
 #endif
 
+namespace string_utils {
+template <typename T>
+bool cast(std::string const & str, std::optional<T> & to) {
+  auto [value, success] = cast<T>(str);
+  if (success) { to = std::move(value); }
+  return true;
+}
+}
+
 // This should be placed last in the file
 namespace string_utils {
 template <typename T> std::pair<T, bool> cast(std::string const & str) {

+ 4 - 1
src/tokenizer.cxx

@@ -76,7 +76,10 @@ tokenizer::operator()(std::string const & input) const {
   // Due to the special handling rules of the truncate feature, we need
   // to add an additional layer of handling around empty tokens and buffer
   if (ignore_empty_tokens_ && equals_from(divider_, from)) { ++from; }
-  if (rval.size() < max_outputs_) {
+  // Additionally, we do not want to include the final element if there is
+  // actually no data remaining in the buffer/input string, even when we permit
+  // empty tokens in our output.
+  if (rval.size() < max_outputs_ && buffer.empty() && from == input.size())) {
     rval.emplace_back(buffer.empty() ? input.substr(from) : buffer);
   }
   return rval;