]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/split.h
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / common / split.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 /*
5 * Ceph - scalable distributed file system
6 *
7 * Copyright (C) 2019 Red Hat, Inc.
8 *
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
13 *
14 */
15
16 #pragma once
17
18 #include <string_view>
19
20 namespace ceph {
21
22 // a forward iterator over the parts of a split string
23 class spliterator {
24 std::string_view str; // full string
25 std::string_view delims; // delimiters
26
27 using size_type = std::string_view::size_type;
28 size_type pos = 0; // start position of current part
29 std::string_view part; // view of current part
30
31 // return the next part after the given position
32 std::string_view next(size_type end) {
33 pos = str.find_first_not_of(delims, end);
34 if (pos == str.npos) {
35 return {};
36 }
37 return str.substr(pos, str.find_first_of(delims, pos) - pos);
38 }
39 public:
40 // types required by std::iterator_traits
41 using difference_type = int;
42 using value_type = std::string_view;
43 using pointer = const value_type*;
44 using reference = const value_type&;
45 using iterator_category = std::forward_iterator_tag;
46
47 spliterator() = default;
48
49 spliterator(std::string_view str, std::string_view delims)
50 : str(str), delims(delims), pos(0), part(next(0))
51 {}
52
53 spliterator& operator++() {
54 part = next(pos + part.size());
55 return *this;
56 }
57 spliterator operator++(int) {
58 spliterator tmp = *this;
59 part = next(pos + part.size());
60 return tmp;
61 }
62
63 reference operator*() const { return part; }
64 pointer operator->() const { return &part; }
65
66 friend bool operator==(const spliterator& lhs, const spliterator& rhs) {
67 return lhs.part.data() == rhs.part.data()
68 && lhs.part.size() == rhs.part.size();
69 }
70 friend bool operator!=(const spliterator& lhs, const spliterator& rhs) {
71 return lhs.part.data() != rhs.part.data()
72 || lhs.part.size() != rhs.part.size();
73 }
74 };
75
76 // represents an immutable range of split string parts
77 //
78 // ranged-for loop example:
79 //
80 // for (std::string_view s : split(input)) {
81 // ...
82 //
83 // container initialization example:
84 //
85 // auto parts = split(input);
86 //
87 // std::vector<std::string> strings;
88 // strings.assign(parts.begin(), parts.end());
89 //
90 class split {
91 std::string_view str; // full string
92 std::string_view delims; // delimiters
93 public:
94 split(std::string_view str, std::string_view delims = ";,= \t\n")
95 : str(str), delims(delims) {}
96
97 using iterator = spliterator;
98 using const_iterator = spliterator;
99
100 iterator begin() const { return {str, delims}; }
101 const_iterator cbegin() const { return {str, delims}; }
102
103 iterator end() const { return {}; }
104 const_iterator cend() const { return {}; }
105 };
106
107 } // namespace ceph