GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-string.cc
Go to the documentation of this file.
1 /*
2 Copyright (C) 2016-2018 CarnĂ« Draug
3 
4 This file is part of Octave.
5 
6 Octave is free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 Octave is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with Octave; see the file COPYING. If not, see
18 <https://www.gnu.org/licenses/>.
19 
20 */
21 
22 #if defined (HAVE_CONFIG_H)
23 # include "config.h"
24 #endif
25 
26 #include "oct-string.h"
27 
28 #include <cctype>
29 #include <cstring>
30 
31 #include <string>
32 
33 #include "Array.h"
34 
35 template <typename T>
36 static bool
37 str_data_cmp (const typename T::value_type *a, const typename T::value_type *b,
38  const typename T::size_type n)
39 {
40  for (typename T::size_type i = 0; i < n; ++i)
41  if (a[i] != b[i])
42  return false;
43  return true;
44 }
45 
46 template <typename T>
47 static bool
48 str_data_cmpi (const typename T::value_type *a, const typename T::value_type *b,
49  const typename T::size_type n)
50 {
51  for (typename T::size_type i = 0; i < n; ++i)
52  if (std::tolower (a[i]) != std::tolower (b[i]))
53  return false;
54  return true;
55 }
56 
57 
58 // Templates to handle std::basic_string, std::vector, Array, and char*.
59 template <typename T>
60 typename T::size_type
61 numel (const T& str)
62 {
63  return str.size ();
64 }
65 
66 template <>
69 {
70  return str.numel ();
71 }
72 
73 template <typename T>
74 typename T::size_type
75 strlen (const typename T::value_type *str)
76 {
77  return std::strlen (str);
78 }
79 
80 template <typename T>
81 bool
82 sizes_cmp (const T& str_a, const T& str_b)
83 {
84  return str_a.size () == str_b.size ();
85 }
86 
87 template <>
88 bool
89 sizes_cmp (const Array<char>& str_a, const Array<char>& str_b)
90 {
91  return str_a.dims () == str_b.dims ();
92 }
93 
94 template <typename T>
95 bool
96 sizes_cmp (const T& str_a, const typename T::value_type *str_b)
97 {
98  return str_a.size () == strlen<T> (str_b);
99 }
100 
101 template <>
102 bool
103 sizes_cmp (const Array<char>& str_a, const char *str_b)
104 {
105  return (str_a.isvector () && str_a.rows () == 1
106  && str_a.numel () == strlen<Array<char>> (str_b));
107 }
108 
109 
110 template<typename T>
111 bool
112 octave::string::strcmp (const T& str_a, const T& str_b)
113 {
114  return (sizes_cmp (str_a, str_b)
115  && str_data_cmp<T> (str_a.data (), str_b.data (), numel (str_a)));
116 }
117 
118 template<typename T>
119 bool
120 octave::string::strcmp (const T& str_a, const typename T::value_type *str_b)
121 {
122  return (sizes_cmp (str_a, str_b)
123  && str_data_cmp<T> (str_a.data (), str_b, numel (str_a)));
124 }
125 
126 
127 template<typename T>
128 bool
129 octave::string::strcmpi (const T& str_a, const T& str_b)
130 {
131  return (sizes_cmp (str_a, str_b)
132  && str_data_cmpi<T> (str_a.data (), str_b.data (), numel (str_a)));
133 }
134 
135 template<typename T>
136 bool
137 octave::string::strcmpi (const T& str_a, const typename T::value_type *str_b)
138 {
139  return (sizes_cmp (str_a, str_b)
140  && str_data_cmpi<T> (str_a.data (), str_b, numel (str_a)));
141 }
142 
143 
144 template<typename T>
145 bool
146 octave::string::strncmp (const T& str_a, const T& str_b,
147  const typename T::size_type n)
148 {
149  return (numel (str_a) >= n && numel (str_b) >= n
150  && str_data_cmp<T> (str_a.data (), str_b.data (), n));
151 }
152 
153 template<typename T>
154 bool
155 octave::string::strncmp (const T& str_a, const typename T::value_type *str_b,
156  const typename T::size_type n)
157 {
158  return (numel (str_a) >= n && strlen<T> (str_b) >= n
159  && str_data_cmp<T> (str_a.data (), str_b, n));
160 }
161 
162 
163 template<typename T>
164 bool
165 octave::string::strncmpi (const T& str_a, const T& str_b,
166  const typename T::size_type n)
167 {
168  return (numel (str_a) >= n && numel (str_b) >= n
169  && str_data_cmpi<T> (str_a.data (), str_b.data (), n));
170 }
171 
172 template<typename T>
173 bool
174 octave::string::strncmpi (const T& str_a, const typename T::value_type *str_b,
175  const typename T::size_type n)
176 {
177  return (numel (str_a) >= n && strlen<T> (str_b) >= n
178  && str_data_cmpi<T> (str_a.data (), str_b, n));
179 }
180 
181 
182 // Instantiations we need
183 #define INSTANTIATE_OCTAVE_STRING(T) \
184  template bool octave::string::strcmp<T> (const T&, const T&); \
185  template bool octave::string::strcmp<T> (const T&, \
186  const typename T::value_type*); \
187  template bool octave::string::strcmpi<T> (const T&, const T&); \
188  template bool octave::string::strcmpi<T> (const T&, \
189  const typename T::value_type*); \
190  template bool octave::string::strncmp<T> (const T&, const T&, \
191  const typename T::size_type); \
192  template bool octave::string::strncmp<T> (const T&, \
193  const typename T::value_type*, \
194  const typename T::size_type); \
195  template bool octave::string::strncmpi<T> (const T&, const T&, \
196  const typename T::size_type n); \
197  template bool octave::string::strncmpi<T> (const T&, \
198  const typename T::value_type*, \
199  const typename T::size_type);
200 
201 // We could also instantiate std::vector<char> but would it be
202 // useful for anyone?
205 
206 #undef INSTANTIATE_OCTAVE_STRING
octave_idx_type rows(void) const
Definition: Array.h:404
static bool str_data_cmp(const typename T::value_type *a, const typename T::value_type *b, const typename T::size_type n)
Definition: oct-string.cc:37
bool isvector(void) const
Definition: Array.h:571
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:442
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
Definition: oct-string.cc:112
std::string str
Definition: hash.cc:118
bool sizes_cmp(const T &str_a, const T &str_b)
Definition: oct-string.cc:82
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:75
static bool str_data_cmpi(const typename T::value_type *a, const typename T::value_type *b, const typename T::size_type n)
Definition: oct-string.cc:48
T::size_type numel(const T &str)
Definition: oct-string.cc:61
bool strcmpi(const T &str_a, const T &str_b)
True if strings are the same, ignoring case.
Definition: oct-string.cc:129
#define INSTANTIATE_OCTAVE_STRING(T)
Definition: oct-string.cc:183
b
Definition: cellfun.cc:400
for i
Definition: data.cc:5264
bool strncmp(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same.
Definition: oct-string.cc:146
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
bool strncmpi(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same, ignoring case.
Definition: oct-string.cc:165
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888