tvl-depot/third_party/abseil_cpp/absl/strings/str_split.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

515 lines
18 KiB
C
Raw Normal View History

2017-09-19 22:54:40 +02:00
//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
2017-09-19 22:54:40 +02:00
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: str_split.h
// -----------------------------------------------------------------------------
//
// This file contains functions for splitting strings. It defines the main
// `StrSplit()` function, several delimiters for determining the boundaries on
// which to split the string, and predicates for filtering delimited results.
2017-09-19 22:54:40 +02:00
// `StrSplit()` adapts the returned collection to the type specified by the
// caller.
//
// Example:
//
// // Splits the given string on commas. Returns the results in a
2017-09-19 22:54:40 +02:00
// // vector of strings.
// std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
// // Can also use ","
// // v[0] == "a", v[1] == "b", v[2] == "c"
//
// See StrSplit() below for more information.
#ifndef ABSL_STRINGS_STR_SPLIT_H_
#define ABSL_STRINGS_STR_SPLIT_H_
#include <algorithm>
#include <cstddef>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
2017-09-19 22:54:40 +02:00
#include "absl/strings/internal/str_split_internal.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
namespace absl {
Export of internal Abseil changes -- c99f979ad34f155fbeeea69b88bdc7458d89a21c by Derek Mauro <dmauro@google.com>: Remove a floating point division by zero test. This isn't testing behavior related to the library, and MSVC warns about it in opt mode. PiperOrigin-RevId: 285220804 -- 68b015491f0dbf1ab547994673281abd1f34cd4b by Gennadiy Rozental <rogeeff@google.com>: This CL introduces following changes to the class FlagImpl: * We eliminate the CommandLineFlagLocks struct. Instead callback guard and callback function are combined into a single CallbackData struct, while primary data lock is stored separately. * CallbackData member of class FlagImpl is initially set to be nullptr and is only allocated and initialized when a flag's callback is being set. For most flags we do not pay for the extra space and extra absl::Mutex now. * Primary data guard is stored in data_guard_ data member. This is a properly aligned character buffer of necessary size. During initialization of the flag we construct absl::Mutex in this space using placement new call. * We now avoid extra value copy after successful attempt to parse value out of string. Instead we swap flag's current value with tentative value we just produced. PiperOrigin-RevId: 285132636 -- ed45d118fb818969eb13094cf7827c885dfc562c by Tom Manshreck <shreck@google.com>: Change null-term* (and nul-term*) to NUL-term* in comments PiperOrigin-RevId: 285036610 -- 729619017944db895ce8d6d29c1995aa2e5628a5 by Derek Mauro <dmauro@google.com>: Use the Posix implementation of thread identity on MinGW. Some versions of MinGW suffer from thread_local bugs. PiperOrigin-RevId: 285022920 -- 39a25493503c76885bc3254c28f66a251c5b5bb0 by Greg Falcon <gfalcon@google.com>: Implementation detail change. Add further ABSL_NAMESPACE_BEGIN and _END annotation macros to files in Abseil. PiperOrigin-RevId: 285012012 GitOrigin-RevId: c99f979ad34f155fbeeea69b88bdc7458d89a21c Change-Id: I4c85d3704e45d11a9ac50d562f39640a6adbedc1
2019-12-12 19:36:03 +01:00
ABSL_NAMESPACE_BEGIN
2017-09-19 22:54:40 +02:00
//------------------------------------------------------------------------------
// Delimiters
//------------------------------------------------------------------------------
//
// `StrSplit()` uses delimiters to define the boundaries between elements in the
// provided input. Several `Delimiter` types are defined below. If a string
2017-09-19 22:54:40 +02:00
// (`const char*`, `std::string`, or `absl::string_view`) is passed in place of
// an explicit `Delimiter` object, `StrSplit()` treats it the same way as if it
// were passed a `ByString` delimiter.
//
// A `Delimiter` is an object with a `Find()` function that knows how to find
// the first occurrence of itself in a given `absl::string_view`.
//
// The following `Delimiter` types are available for use within `StrSplit()`:
//
// - `ByString` (default for string arguments)
2017-09-19 22:54:40 +02:00
// - `ByChar` (default for a char argument)
// - `ByAnyChar`
// - `ByLength`
// - `MaxSplits`
//
Export of internal Abseil changes. -- 3d20ce6cd6541579abecaba169d4b8716d511272 by Jon Cohen <cohenjon@google.com>: Only use LSAN for clang version >= 3.5. This should fix https://github.com/abseil/abseil-cpp/issues/244 PiperOrigin-RevId: 234675129 -- e15bd4ec7a81aa95cc3d09fa1e0e81d58ae478fb by Conrad Parker <conradparker@google.com>: Fix errors in apply() sample code The following changes are made: * Make the example method public. * Give the two user functions different names to avoid confusion about whether apply() can select the correct overload of a function based on its tuple argument (it can't). * Pass tuple2 to the second example apply() invocation, instead of passing its contents individually. * Fix a s/tuple/tuple3/ typo in the third example apply() invocation. PiperOrigin-RevId: 234223407 -- de0ed71e21bc76ddf9fe715fdbaef74cd0df95c7 by Abseil Team <absl-team@google.com>: First test if a macro is defined to avoid -Wundef. ABSL clients may need to compile their code with the -Wundef warning flag. It will be helpful if ABSL header files can be compiled without the -Wundef warning. How to avoid the -Wundef warning: If a macro may be undefined, we need to first test whether the macro is defined before testing its value. We can't rely on the C preprocessor rule that an undefined macro has the value 0L. PiperOrigin-RevId: 234201123 -- fa484ad7dae0cac21140a96662809ecb0ec8eb5d by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 234185697 -- d69b1baef681e27954b065375ecf9c2320463b2b by Samuel Benzaquen <sbenza@google.com>: Mix pointers more thoroughly. Some pointer alignments interact badly with the mixing constant. By mixing twice we reduce this problem. PiperOrigin-RevId: 234178401 -- 1041d0e474610f3a8fea0db90958857327d6da1c by Samuel Benzaquen <sbenza@google.com>: Record rehashes in the hashtablez struct. Only recording the probe length on insertion causes a huge overestimation of the total probe length at any given time. With natural growth, elements are inserted when the load factor is between (max load/2, max load). However, after a rehash the majority of elements are actually inserted when the load factor is less than max/2 and have a much lower average probe length. Also reset some values when the table is cleared. PiperOrigin-RevId: 234013580 -- 299205caf3c89c47339f7409bc831746602cea84 by Mark Barolak <mbar@google.com>: Fix a sample code snippet that assumes `absl::string_view::const_iterator` is `const char*`. This is generally true, however in C++17 builds, absl::string_view is an alias for std::string_view and on MSVC, the std::string_view::const_iterator is an object instead of just a pointer. PiperOrigin-RevId: 233844595 -- af6c6370cf51a1e6c1469c79dfb2a486a4009136 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 233773470 -- 6e59e4b8e2bb6101b448f0f32b0bea81fe399ccf by Abseil Team <absl-team@google.com>: fix typo in {Starts|Ends}WithIgnoreCase comment in match.h PiperOrigin-RevId: 233662951 GitOrigin-RevId: 3d20ce6cd6541579abecaba169d4b8716d511272 Change-Id: Ib9a29b1c38c6aedf5d9f3f7f00596e8d30e864dd
2019-02-19 23:29:09 +01:00
// A Delimiter's `Find()` member function will be passed an input `text` that is
// to be split and a position (`pos`) to begin searching for the next delimiter
// in `text`. The returned absl::string_view should refer to the next occurrence
// (after `pos`) of the represented delimiter; this returned absl::string_view
// represents the next location where the input `text` should be broken.
//
// The returned absl::string_view may be zero-length if the Delimiter does not
// represent a part of the string (e.g., a fixed-length delimiter). If no
// delimiter is found in the input `text`, a zero-length absl::string_view
// referring to `text.end()` should be returned (e.g.,
// `text.substr(text.size())`). It is important that the returned
// absl::string_view always be within the bounds of the input `text` given as an
// argument--it must not refer to a string that is physically located outside of
// the given string.
2017-09-19 22:54:40 +02:00
//
// The following example is a simple Delimiter object that is created with a
Export of internal Abseil changes. -- 3d20ce6cd6541579abecaba169d4b8716d511272 by Jon Cohen <cohenjon@google.com>: Only use LSAN for clang version >= 3.5. This should fix https://github.com/abseil/abseil-cpp/issues/244 PiperOrigin-RevId: 234675129 -- e15bd4ec7a81aa95cc3d09fa1e0e81d58ae478fb by Conrad Parker <conradparker@google.com>: Fix errors in apply() sample code The following changes are made: * Make the example method public. * Give the two user functions different names to avoid confusion about whether apply() can select the correct overload of a function based on its tuple argument (it can't). * Pass tuple2 to the second example apply() invocation, instead of passing its contents individually. * Fix a s/tuple/tuple3/ typo in the third example apply() invocation. PiperOrigin-RevId: 234223407 -- de0ed71e21bc76ddf9fe715fdbaef74cd0df95c7 by Abseil Team <absl-team@google.com>: First test if a macro is defined to avoid -Wundef. ABSL clients may need to compile their code with the -Wundef warning flag. It will be helpful if ABSL header files can be compiled without the -Wundef warning. How to avoid the -Wundef warning: If a macro may be undefined, we need to first test whether the macro is defined before testing its value. We can't rely on the C preprocessor rule that an undefined macro has the value 0L. PiperOrigin-RevId: 234201123 -- fa484ad7dae0cac21140a96662809ecb0ec8eb5d by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 234185697 -- d69b1baef681e27954b065375ecf9c2320463b2b by Samuel Benzaquen <sbenza@google.com>: Mix pointers more thoroughly. Some pointer alignments interact badly with the mixing constant. By mixing twice we reduce this problem. PiperOrigin-RevId: 234178401 -- 1041d0e474610f3a8fea0db90958857327d6da1c by Samuel Benzaquen <sbenza@google.com>: Record rehashes in the hashtablez struct. Only recording the probe length on insertion causes a huge overestimation of the total probe length at any given time. With natural growth, elements are inserted when the load factor is between (max load/2, max load). However, after a rehash the majority of elements are actually inserted when the load factor is less than max/2 and have a much lower average probe length. Also reset some values when the table is cleared. PiperOrigin-RevId: 234013580 -- 299205caf3c89c47339f7409bc831746602cea84 by Mark Barolak <mbar@google.com>: Fix a sample code snippet that assumes `absl::string_view::const_iterator` is `const char*`. This is generally true, however in C++17 builds, absl::string_view is an alias for std::string_view and on MSVC, the std::string_view::const_iterator is an object instead of just a pointer. PiperOrigin-RevId: 233844595 -- af6c6370cf51a1e6c1469c79dfb2a486a4009136 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 233773470 -- 6e59e4b8e2bb6101b448f0f32b0bea81fe399ccf by Abseil Team <absl-team@google.com>: fix typo in {Starts|Ends}WithIgnoreCase comment in match.h PiperOrigin-RevId: 233662951 GitOrigin-RevId: 3d20ce6cd6541579abecaba169d4b8716d511272 Change-Id: Ib9a29b1c38c6aedf5d9f3f7f00596e8d30e864dd
2019-02-19 23:29:09 +01:00
// single char and will look for that char in the text passed to the `Find()`
2017-09-19 22:54:40 +02:00
// function:
//
// struct SimpleDelimiter {
// const char c_;
// explicit SimpleDelimiter(char c) : c_(c) {}
// absl::string_view Find(absl::string_view text, size_t pos) {
// auto found = text.find(c_, pos);
// if (found == absl::string_view::npos)
// return text.substr(text.size());
2017-09-19 22:54:40 +02:00
//
// return text.substr(found, 1);
2017-09-19 22:54:40 +02:00
// }
// };
// ByString
//
// A sub-string delimiter. If `StrSplit()` is passed a string in place of a
// `Delimiter` object, the string will be implicitly converted into a
2017-09-19 22:54:40 +02:00
// `ByString` delimiter.
//
// Example:
//
// // Because a string literal is converted to an `absl::ByString`,
2017-09-19 22:54:40 +02:00
// // the following two splits are equivalent.
//
// std::vector<std::string> v1 = absl::StrSplit("a, b, c", ", ");
//
// using absl::ByString;
// std::vector<std::string> v2 = absl::StrSplit("a, b, c",
// ByString(", "));
Changes imported from Abseil "staging" branch: - 43853019b439efb32c79d5d50e24508588e1bbe0 Undo the not applying qualifications to absl types in enc... by Derek Mauro <dmauro@google.com> - 06d62a10621c9864279ee57097069cfe3cb7b42a fix capitalization by Abseil Team <absl-team@google.com> - 22adbfee340bb452ba38b68975ade6f072859c4a Fix indices in str_split.h comments. by Derek Mauro <dmauro@google.com> - ae5143a559ad8633a78cd76620e30a781006d088 Fix the inconsistent licenses directives in the BUILD fil... by Derek Mauro <dmauro@google.com> - 0a76a3653b2ecfdad433d3e2f5b651c4ecdcf74b Remove strip.cc, fastmem.h, and fastmem_test.cc from the ... by Derek Mauro <dmauro@google.com> - 77908cfce5927aabca1f8d62481106f22cfc1936 Internal change. by Derek Mauro <dmauro@google.com> - d3277b4171f37e22ab346becb5e295c36c7a0219 Be consistent in (not) applying qualifications for enclos... by Abseil Team <absl-team@google.com> - 9ec7f8164e7d6a5f64288a7360a346628393cc50 Add std:: qualification to isnan and isinf in duration_te... by Derek Mauro <dmauro@google.com> - 9f7c87d7764ddba05286fabca1f4f15285f3250a Fix typos in string_view comments. by Abseil Team <absl-team@google.com> - 281860804f8053143d969b99876e3dbc6deb1236 Fix typo in container.h docs. by Abseil Team <absl-team@google.com> - 0b0a9388c7a9d7f72349d44b5b46132f45bde56c Add bazel-* symlinks to gitignore. by Michael Pratt <mpratt@google.com> GitOrigin-RevId: 43853019b439efb32c79d5d50e24508588e1bbe0 Change-Id: I9e74a5430816a34ecf1acb86486ed3b0bd12a1d6
2017-09-27 19:50:48 +02:00
// // v[0] == "a", v[1] == "b", v[2] == "c"
2017-09-19 22:54:40 +02:00
class ByString {
public:
explicit ByString(absl::string_view sp);
absl::string_view Find(absl::string_view text, size_t pos) const;
private:
const std::string delimiter_;
};
// ByChar
//
// A single character delimiter. `ByChar` is functionally equivalent to a
// 1-char string within a `ByString` delimiter, but slightly more efficient.
2017-09-19 22:54:40 +02:00
//
// Example:
//
// // Because a char literal is converted to a absl::ByChar,
// // the following two splits are equivalent.
// std::vector<std::string> v1 = absl::StrSplit("a,b,c", ',');
// using absl::ByChar;
// std::vector<std::string> v2 = absl::StrSplit("a,b,c", ByChar(','));
Changes imported from Abseil "staging" branch: - 43853019b439efb32c79d5d50e24508588e1bbe0 Undo the not applying qualifications to absl types in enc... by Derek Mauro <dmauro@google.com> - 06d62a10621c9864279ee57097069cfe3cb7b42a fix capitalization by Abseil Team <absl-team@google.com> - 22adbfee340bb452ba38b68975ade6f072859c4a Fix indices in str_split.h comments. by Derek Mauro <dmauro@google.com> - ae5143a559ad8633a78cd76620e30a781006d088 Fix the inconsistent licenses directives in the BUILD fil... by Derek Mauro <dmauro@google.com> - 0a76a3653b2ecfdad433d3e2f5b651c4ecdcf74b Remove strip.cc, fastmem.h, and fastmem_test.cc from the ... by Derek Mauro <dmauro@google.com> - 77908cfce5927aabca1f8d62481106f22cfc1936 Internal change. by Derek Mauro <dmauro@google.com> - d3277b4171f37e22ab346becb5e295c36c7a0219 Be consistent in (not) applying qualifications for enclos... by Abseil Team <absl-team@google.com> - 9ec7f8164e7d6a5f64288a7360a346628393cc50 Add std:: qualification to isnan and isinf in duration_te... by Derek Mauro <dmauro@google.com> - 9f7c87d7764ddba05286fabca1f4f15285f3250a Fix typos in string_view comments. by Abseil Team <absl-team@google.com> - 281860804f8053143d969b99876e3dbc6deb1236 Fix typo in container.h docs. by Abseil Team <absl-team@google.com> - 0b0a9388c7a9d7f72349d44b5b46132f45bde56c Add bazel-* symlinks to gitignore. by Michael Pratt <mpratt@google.com> GitOrigin-RevId: 43853019b439efb32c79d5d50e24508588e1bbe0 Change-Id: I9e74a5430816a34ecf1acb86486ed3b0bd12a1d6
2017-09-27 19:50:48 +02:00
// // v[0] == "a", v[1] == "b", v[2] == "c"
2017-09-19 22:54:40 +02:00
//
// `ByChar` is also the default delimiter if a single character is given
// as the delimiter to `StrSplit()`. For example, the following calls are
// equivalent:
//
// std::vector<std::string> v = absl::StrSplit("a-b", '-');
//
// using absl::ByChar;
// std::vector<std::string> v = absl::StrSplit("a-b", ByChar('-'));
//
class ByChar {
public:
explicit ByChar(char c) : c_(c) {}
absl::string_view Find(absl::string_view text, size_t pos) const;
private:
char c_;
};
// ByAnyChar
//
// A delimiter that will match any of the given byte-sized characters within
// its provided string.
2017-09-19 22:54:40 +02:00
//
// Note: this delimiter works with single-byte string data, but does not work
2017-09-19 22:54:40 +02:00
// with variable-width encodings, such as UTF-8.
//
// Example:
//
// using absl::ByAnyChar;
// std::vector<std::string> v = absl::StrSplit("a,b=c", ByAnyChar(",="));
Changes imported from Abseil "staging" branch: - 43853019b439efb32c79d5d50e24508588e1bbe0 Undo the not applying qualifications to absl types in enc... by Derek Mauro <dmauro@google.com> - 06d62a10621c9864279ee57097069cfe3cb7b42a fix capitalization by Abseil Team <absl-team@google.com> - 22adbfee340bb452ba38b68975ade6f072859c4a Fix indices in str_split.h comments. by Derek Mauro <dmauro@google.com> - ae5143a559ad8633a78cd76620e30a781006d088 Fix the inconsistent licenses directives in the BUILD fil... by Derek Mauro <dmauro@google.com> - 0a76a3653b2ecfdad433d3e2f5b651c4ecdcf74b Remove strip.cc, fastmem.h, and fastmem_test.cc from the ... by Derek Mauro <dmauro@google.com> - 77908cfce5927aabca1f8d62481106f22cfc1936 Internal change. by Derek Mauro <dmauro@google.com> - d3277b4171f37e22ab346becb5e295c36c7a0219 Be consistent in (not) applying qualifications for enclos... by Abseil Team <absl-team@google.com> - 9ec7f8164e7d6a5f64288a7360a346628393cc50 Add std:: qualification to isnan and isinf in duration_te... by Derek Mauro <dmauro@google.com> - 9f7c87d7764ddba05286fabca1f4f15285f3250a Fix typos in string_view comments. by Abseil Team <absl-team@google.com> - 281860804f8053143d969b99876e3dbc6deb1236 Fix typo in container.h docs. by Abseil Team <absl-team@google.com> - 0b0a9388c7a9d7f72349d44b5b46132f45bde56c Add bazel-* symlinks to gitignore. by Michael Pratt <mpratt@google.com> GitOrigin-RevId: 43853019b439efb32c79d5d50e24508588e1bbe0 Change-Id: I9e74a5430816a34ecf1acb86486ed3b0bd12a1d6
2017-09-27 19:50:48 +02:00
// // v[0] == "a", v[1] == "b", v[2] == "c"
2017-09-19 22:54:40 +02:00
//
// If `ByAnyChar` is given the empty string, it behaves exactly like
// `ByString` and matches each individual character in the input string.
2017-09-19 22:54:40 +02:00
//
class ByAnyChar {
public:
explicit ByAnyChar(absl::string_view sp);
absl::string_view Find(absl::string_view text, size_t pos) const;
private:
const std::string delimiters_;
};
// ByLength
//
// A delimiter for splitting into equal-length strings. The length argument to
// the constructor must be greater than 0.
//
// Note: this delimiter works with single-byte string data, but does not work
2017-09-19 22:54:40 +02:00
// with variable-width encodings, such as UTF-8.
//
// Example:
//
// using absl::ByLength;
// std::vector<std::string> v = absl::StrSplit("123456789", ByLength(3));
// // v[0] == "123", v[1] == "456", v[2] == "789"
//
// Note that the string does not have to be a multiple of the fixed split
2017-09-19 22:54:40 +02:00
// length. In such a case, the last substring will be shorter.
//
// using absl::ByLength;
// std::vector<std::string> v = absl::StrSplit("12345", ByLength(2));
//
// // v[0] == "12", v[1] == "34", v[2] == "5"
2017-09-19 22:54:40 +02:00
class ByLength {
public:
explicit ByLength(ptrdiff_t length);
absl::string_view Find(absl::string_view text, size_t pos) const;
private:
const ptrdiff_t length_;
};
namespace strings_internal {
// A traits-like metafunction for selecting the default Delimiter object type
// for a particular Delimiter type. The base case simply exposes type Delimiter
// itself as the delimiter's Type. However, there are specializations for
// string-like objects that map them to the ByString delimiter object.
2017-09-19 22:54:40 +02:00
// This allows functions like absl::StrSplit() and absl::MaxSplits() to accept
// string-like objects (e.g., ',') as delimiter arguments but they will be
2017-09-19 22:54:40 +02:00
// treated as if a ByString delimiter was given.
template <typename Delimiter>
struct SelectDelimiter {
using type = Delimiter;
};
template <>
struct SelectDelimiter<char> {
using type = ByChar;
};
template <>
struct SelectDelimiter<char*> {
using type = ByString;
};
template <>
struct SelectDelimiter<const char*> {
using type = ByString;
};
template <>
struct SelectDelimiter<absl::string_view> {
using type = ByString;
};
template <>
struct SelectDelimiter<std::string> {
using type = ByString;
};
// Wraps another delimiter and sets a max number of matches for that delimiter.
template <typename Delimiter>
class MaxSplitsImpl {
public:
MaxSplitsImpl(Delimiter delimiter, int limit)
: delimiter_(delimiter), limit_(limit), count_(0) {}
absl::string_view Find(absl::string_view text, size_t pos) {
if (count_++ == limit_) {
return absl::string_view(text.data() + text.size(),
0); // No more matches.
2017-09-19 22:54:40 +02:00
}
return delimiter_.Find(text, pos);
}
private:
Delimiter delimiter_;
const int limit_;
int count_;
};
} // namespace strings_internal
// MaxSplits()
//
// A delimiter that limits the number of matches which can occur to the passed
// `limit`. The last element in the returned collection will contain all
// remaining unsplit pieces, which may contain instances of the delimiter.
// The collection will contain at most `limit` + 1 elements.
// Example:
//
// using absl::MaxSplits;
// std::vector<std::string> v = absl::StrSplit("a,b,c", MaxSplits(',', 1));
//
// // v[0] == "a", v[1] == "b,c"
template <typename Delimiter>
inline strings_internal::MaxSplitsImpl<
typename strings_internal::SelectDelimiter<Delimiter>::type>
MaxSplits(Delimiter delimiter, int limit) {
typedef
typename strings_internal::SelectDelimiter<Delimiter>::type DelimiterType;
return strings_internal::MaxSplitsImpl<DelimiterType>(
DelimiterType(delimiter), limit);
}
//------------------------------------------------------------------------------
// Predicates
//------------------------------------------------------------------------------
//
// Predicates filter the results of a `StrSplit()` by determining whether or not
// a resultant element is included in the result set. A predicate may be passed
// as an optional third argument to the `StrSplit()` function.
//
// Predicates are unary functions (or functors) that take a single
// `absl::string_view` argument and return a bool indicating whether the
// argument should be included (`true`) or excluded (`false`).
//
// Predicates are useful when filtering out empty substrings. By default, empty
// substrings may be returned by `StrSplit()`, which is similar to the way split
// functions work in other programming languages.
// AllowEmpty()
//
// Always returns `true`, indicating that all strings--including empty
// strings--should be included in the split output. This predicate is not
// strictly needed because this is the default behavior of `StrSplit()`;
// however, it might be useful at some call sites to make the intent explicit.
//
// Example:
//
// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', AllowEmpty());
//
// // v[0] == " a ", v[1] == " ", v[2] == "", v[3] = "b", v[4] == ""
struct AllowEmpty {
bool operator()(absl::string_view) const { return true; }
};
// SkipEmpty()
//
// Returns `false` if the given `absl::string_view` is empty, indicating that
// `StrSplit()` should omit the empty string.
2017-09-19 22:54:40 +02:00
//
// Example:
//
// std::vector<std::string> v = absl::StrSplit(",a,,b,", ',', SkipEmpty());
//
// // v[0] == "a", v[1] == "b"
//
// Note: `SkipEmpty()` does not consider a string containing only whitespace
2017-09-19 22:54:40 +02:00
// to be empty. To skip such whitespace as well, use the `SkipWhitespace()`
// predicate.
struct SkipEmpty {
bool operator()(absl::string_view sp) const { return !sp.empty(); }
};
// SkipWhitespace()
//
// Returns `false` if the given `absl::string_view` is empty *or* contains only
// whitespace, indicating that `StrSplit()` should omit the string.
2017-09-19 22:54:40 +02:00
//
// Example:
//
// std::vector<std::string> v = absl::StrSplit(" a , ,,b,",
// ',', SkipWhitespace());
// // v[0] == " a ", v[1] == "b"
//
// // SkipEmpty() would return whitespace elements
// std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', SkipEmpty());
// // v[0] == " a ", v[1] == " ", v[2] == "b"
struct SkipWhitespace {
bool operator()(absl::string_view sp) const {
sp = absl::StripAsciiWhitespace(sp);
return !sp.empty();
}
};
//------------------------------------------------------------------------------
// StrSplit()
//------------------------------------------------------------------------------
// StrSplit()
//
// Splits a given string based on the provided `Delimiter` object, returning the
// elements within the type specified by the caller. Optionally, you may pass a
// `Predicate` to `StrSplit()` indicating whether to include or exclude the
// resulting element within the final result set. (See the overviews for
// Delimiters and Predicates above.)
2017-09-19 22:54:40 +02:00
//
// Example:
//
// std::vector<std::string> v = absl::StrSplit("a,b,c,d", ',');
// // v[0] == "a", v[1] == "b", v[2] == "c", v[3] == "d"
//
// You can also provide an explicit `Delimiter` object:
//
// Example:
//
// using absl::ByAnyChar;
// std::vector<std::string> v = absl::StrSplit("a,b=c", ByAnyChar(",="));
Changes imported from Abseil "staging" branch: - 43853019b439efb32c79d5d50e24508588e1bbe0 Undo the not applying qualifications to absl types in enc... by Derek Mauro <dmauro@google.com> - 06d62a10621c9864279ee57097069cfe3cb7b42a fix capitalization by Abseil Team <absl-team@google.com> - 22adbfee340bb452ba38b68975ade6f072859c4a Fix indices in str_split.h comments. by Derek Mauro <dmauro@google.com> - ae5143a559ad8633a78cd76620e30a781006d088 Fix the inconsistent licenses directives in the BUILD fil... by Derek Mauro <dmauro@google.com> - 0a76a3653b2ecfdad433d3e2f5b651c4ecdcf74b Remove strip.cc, fastmem.h, and fastmem_test.cc from the ... by Derek Mauro <dmauro@google.com> - 77908cfce5927aabca1f8d62481106f22cfc1936 Internal change. by Derek Mauro <dmauro@google.com> - d3277b4171f37e22ab346becb5e295c36c7a0219 Be consistent in (not) applying qualifications for enclos... by Abseil Team <absl-team@google.com> - 9ec7f8164e7d6a5f64288a7360a346628393cc50 Add std:: qualification to isnan and isinf in duration_te... by Derek Mauro <dmauro@google.com> - 9f7c87d7764ddba05286fabca1f4f15285f3250a Fix typos in string_view comments. by Abseil Team <absl-team@google.com> - 281860804f8053143d969b99876e3dbc6deb1236 Fix typo in container.h docs. by Abseil Team <absl-team@google.com> - 0b0a9388c7a9d7f72349d44b5b46132f45bde56c Add bazel-* symlinks to gitignore. by Michael Pratt <mpratt@google.com> GitOrigin-RevId: 43853019b439efb32c79d5d50e24508588e1bbe0 Change-Id: I9e74a5430816a34ecf1acb86486ed3b0bd12a1d6
2017-09-27 19:50:48 +02:00
// // v[0] == "a", v[1] == "b", v[2] == "c"
2017-09-19 22:54:40 +02:00
//
// See above for more information on delimiters.
//
// By default, empty strings are included in the result set. You can optionally
// include a third `Predicate` argument to apply a test for whether the
// resultant element should be included in the result set:
//
// Example:
//
// std::vector<std::string> v = absl::StrSplit(" a , ,,b,",
// ',', SkipWhitespace());
// // v[0] == " a ", v[1] == "b"
2017-09-19 22:54:40 +02:00
//
// See above for more information on predicates.
//
//------------------------------------------------------------------------------
// StrSplit() Return Types
//------------------------------------------------------------------------------
//
// The `StrSplit()` function adapts the returned collection to the collection
// specified by the caller (e.g. `std::vector` above). The returned collections
// may contain `std::string`, `absl::string_view` (in which case the original
// string being split must ensure that it outlives the collection), or any
// object that can be explicitly created from an `absl::string_view`. This
// behavior works for:
2017-09-19 22:54:40 +02:00
//
// 1) All standard STL containers including `std::vector`, `std::list`,
// `std::deque`, `std::set`,`std::multiset`, 'std::map`, and `std::multimap`
// 2) `std::pair` (which is not actually a container). See below.
//
// Example:
//
// // The results are returned as `absl::string_view` objects. Note that we
// // have to ensure that the input string outlives any results.
2017-09-19 22:54:40 +02:00
// std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ',');
//
// // Stores results in a std::set<std::string>, which also performs
// // de-duplication and orders the elements in ascending order.
// std::set<std::string> a = absl::StrSplit("b,a,c,a,b", ',');
// // v[0] == "a", v[1] == "b", v[2] = "c"
//
// // `StrSplit()` can be used within a range-based for loop, in which case
// // each element will be of type `absl::string_view`.
// std::vector<std::string> v;
// for (const auto sv : absl::StrSplit("a,b,c", ',')) {
// if (sv != "b") v.emplace_back(sv);
// }
// // v[0] == "a", v[1] == "c"
//
// // Stores results in a map. The map implementation assumes that the input
// // is provided as a series of key/value pairs. For example, the 0th element
// // resulting from the split will be stored as a key to the 1st element. If
// // an odd number of elements are resolved, the last element is paired with
// // a default-constructed value (e.g., empty string).
2017-09-19 22:54:40 +02:00
// std::map<std::string, std::string> m = absl::StrSplit("a,b,c", ',');
// // m["a"] == "b", m["c"] == "" // last component value equals ""
//
// Splitting to `std::pair` is an interesting case because it can hold only two
// elements and is not a collection type. When splitting to a `std::pair` the
// first two split strings become the `std::pair` `.first` and `.second`
// members, respectively. The remaining split substrings are discarded. If there
// are less than two split substrings, the empty string is used for the
2017-09-19 22:54:40 +02:00
// corresponding
// `std::pair` member.
//
// Example:
//
// // Stores first two split strings as the members in a std::pair.
// std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ',');
2017-09-19 22:54:40 +02:00
// // p.first == "a", p.second == "b" // "c" is omitted.
//
// The `StrSplit()` function can be used multiple times to perform more
// complicated splitting logic, such as intelligently parsing key-value pairs.
//
// Example:
//
// // The input string "a=b=c,d=e,f=,g" becomes
2017-09-19 22:54:40 +02:00
// // { "a" => "b=c", "d" => "e", "f" => "", "g" => "" }
// std::map<std::string, std::string> m;
2017-09-19 22:54:40 +02:00
// for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) {
// m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1)));
// }
// EXPECT_EQ("b=c", m.find("a")->second);
// EXPECT_EQ("e", m.find("d")->second);
// EXPECT_EQ("", m.find("f")->second);
// EXPECT_EQ("", m.find("g")->second);
//
// WARNING: Due to a legacy bug that is maintained for backward compatibility,
// splitting the following empty string_views produces different results:
//
// absl::StrSplit(absl::string_view(""), '-'); // {""}
// absl::StrSplit(absl::string_view(), '-'); // {}, but should be {""}
//
// Try not to depend on this distinction because the bug may one day be fixed.
template <typename Delimiter>
strings_internal::Splitter<
typename strings_internal::SelectDelimiter<Delimiter>::type, AllowEmpty>
StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d) {
using DelimiterType =
typename strings_internal::SelectDelimiter<Delimiter>::type;
return strings_internal::Splitter<DelimiterType, AllowEmpty>(
std::move(text), DelimiterType(d), AllowEmpty());
}
template <typename Delimiter, typename Predicate>
strings_internal::Splitter<
typename strings_internal::SelectDelimiter<Delimiter>::type, Predicate>
StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d,
Predicate p) {
using DelimiterType =
typename strings_internal::SelectDelimiter<Delimiter>::type;
return strings_internal::Splitter<DelimiterType, Predicate>(
std::move(text), DelimiterType(d), std::move(p));
}
Export of internal Abseil changes -- c99f979ad34f155fbeeea69b88bdc7458d89a21c by Derek Mauro <dmauro@google.com>: Remove a floating point division by zero test. This isn't testing behavior related to the library, and MSVC warns about it in opt mode. PiperOrigin-RevId: 285220804 -- 68b015491f0dbf1ab547994673281abd1f34cd4b by Gennadiy Rozental <rogeeff@google.com>: This CL introduces following changes to the class FlagImpl: * We eliminate the CommandLineFlagLocks struct. Instead callback guard and callback function are combined into a single CallbackData struct, while primary data lock is stored separately. * CallbackData member of class FlagImpl is initially set to be nullptr and is only allocated and initialized when a flag's callback is being set. For most flags we do not pay for the extra space and extra absl::Mutex now. * Primary data guard is stored in data_guard_ data member. This is a properly aligned character buffer of necessary size. During initialization of the flag we construct absl::Mutex in this space using placement new call. * We now avoid extra value copy after successful attempt to parse value out of string. Instead we swap flag's current value with tentative value we just produced. PiperOrigin-RevId: 285132636 -- ed45d118fb818969eb13094cf7827c885dfc562c by Tom Manshreck <shreck@google.com>: Change null-term* (and nul-term*) to NUL-term* in comments PiperOrigin-RevId: 285036610 -- 729619017944db895ce8d6d29c1995aa2e5628a5 by Derek Mauro <dmauro@google.com>: Use the Posix implementation of thread identity on MinGW. Some versions of MinGW suffer from thread_local bugs. PiperOrigin-RevId: 285022920 -- 39a25493503c76885bc3254c28f66a251c5b5bb0 by Greg Falcon <gfalcon@google.com>: Implementation detail change. Add further ABSL_NAMESPACE_BEGIN and _END annotation macros to files in Abseil. PiperOrigin-RevId: 285012012 GitOrigin-RevId: c99f979ad34f155fbeeea69b88bdc7458d89a21c Change-Id: I4c85d3704e45d11a9ac50d562f39640a6adbedc1
2019-12-12 19:36:03 +01:00
ABSL_NAMESPACE_END
2017-09-19 22:54:40 +02:00
} // namespace absl
#endif // ABSL_STRINGS_STR_SPLIT_H_