1 /*******************************************************************************
2  * tlx/string/trim.cpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2007-2017 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #include <tlx/string/trim.hpp>
12 
13 #include <algorithm>
14 #include <cstring>
15 
16 namespace tlx {
17 
18 /******************************************************************************/
19 
trim(std::string * str)20 std::string& trim(std::string* str) {
21     return trim(str, " \r\n\t");
22 }
23 
trim(std::string * str,const char * drop)24 std::string& trim(std::string* str, const char* drop) {
25     std::string::size_type pos = str->find_last_not_of(drop);
26     if (pos != std::string::npos) {
27         str->erase(pos + 1);
28         pos = str->find_first_not_of(drop);
29         if (pos != std::string::npos) str->erase(0, pos);
30     }
31     else
32         str->erase(str->begin(), str->end());
33 
34     return *str;
35 }
36 
trim(std::string * str,const std::string & drop)37 std::string& trim(std::string* str, const std::string& drop) {
38     std::string::size_type pos = str->find_last_not_of(drop);
39     if (pos != std::string::npos) {
40         str->erase(pos + 1);
41         pos = str->find_first_not_of(drop);
42         if (pos != std::string::npos) str->erase(0, pos);
43     }
44     else
45         str->erase(str->begin(), str->end());
46 
47     return *str;
48 }
49 
trim(const std::string & str)50 std::string trim(const std::string& str) {
51     return trim(str, " \r\n\t");
52 }
53 
trim(const std::string & str,const char * drop)54 std::string trim(const std::string& str, const char* drop) {
55     // trim beginning
56     std::string::size_type pos1 = str.find_first_not_of(drop);
57     if (pos1 == std::string::npos) return std::string();
58 
59     // copy middle and end
60     std::string out = str.substr(pos1, std::string::npos);
61 
62     // trim end
63     std::string::size_type pos2 = out.find_last_not_of(drop);
64     if (pos2 != std::string::npos)
65         out.erase(pos2 + 1);
66 
67     return out;
68 }
69 
trim(const std::string & str,const std::string & drop)70 std::string trim(const std::string& str,
71                  const std::string& drop) {
72     std::string out;
73     out.reserve(str.size());
74 
75     // trim beginning
76     std::string::const_iterator it = str.begin();
77     while (it != str.end() && drop.find(*it) != std::string::npos)
78         ++it;
79 
80     // copy middle and end
81     out.resize(str.end() - it);
82     std::copy(it, str.end(), out.begin());
83 
84     // trim end
85     std::string::size_type pos = out.find_last_not_of(drop);
86     if (pos != std::string::npos)
87         out.erase(pos + 1);
88 
89     return out;
90 }
91 
92 /******************************************************************************/
93 
trim_right(std::string * str)94 std::string& trim_right(std::string* str) {
95     return trim_right(str, " \r\n\t");
96 }
97 
trim_right(std::string * str,const char * drop)98 std::string& trim_right(std::string* str, const char* drop) {
99     str->erase(str->find_last_not_of(drop) + 1, std::string::npos);
100     return *str;
101 }
102 
trim_right(std::string * str,const std::string & drop)103 std::string& trim_right(std::string* str, const std::string& drop) {
104     str->erase(str->find_last_not_of(drop) + 1, std::string::npos);
105     return *str;
106 }
107 
trim_right(const std::string & str)108 std::string trim_right(const std::string& str) {
109     return trim_right(str, " \r\n\t");
110 }
111 
trim_right(const std::string & str,const char * drop)112 std::string trim_right(const std::string& str, const char* drop) {
113     std::string::size_type pos = str.find_last_not_of(drop);
114     if (pos == std::string::npos) return std::string();
115 
116     return str.substr(0, pos + 1);
117 }
118 
trim_right(const std::string & str,const std::string & drop)119 std::string trim_right(const std::string& str, const std::string& drop) {
120     std::string::size_type pos = str.find_last_not_of(drop);
121     if (pos == std::string::npos) return std::string();
122 
123     return str.substr(0, pos + 1);
124 }
125 
126 /******************************************************************************/
127 
trim_left(std::string * str)128 std::string& trim_left(std::string* str) {
129     return trim_left(str, " \r\n\t");
130 }
131 
trim_left(std::string * str,const char * drop)132 std::string& trim_left(std::string* str, const char* drop) {
133     str->erase(0, str->find_first_not_of(drop));
134     return *str;
135 }
136 
trim_left(std::string * str,const std::string & drop)137 std::string& trim_left(std::string* str, const std::string& drop) {
138     str->erase(0, str->find_first_not_of(drop));
139     return *str;
140 }
141 
trim_left(const std::string & str)142 std::string trim_left(const std::string& str) {
143     return trim_left(str, " \r\n\t");
144 }
145 
trim_left(const std::string & str,const char * drop)146 std::string trim_left(const std::string& str, const char* drop) {
147     std::string::size_type pos = str.find_first_not_of(drop);
148     if (pos == std::string::npos) return std::string();
149 
150     return str.substr(pos, std::string::npos);
151 }
152 
trim_left(const std::string & str,const std::string & drop)153 std::string trim_left(const std::string& str, const std::string& drop) {
154     std::string::size_type pos = str.find_first_not_of(drop);
155     if (pos == std::string::npos) return std::string();
156 
157     return str.substr(pos, std::string::npos);
158 }
159 
160 } // namespace tlx
161 
162 /******************************************************************************/
163