2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 // Copyright 2017-2019 Martin Moene
37 // https://github.com/martinmoene/string-view-lite
39 // Distributed under the Boost Software License, Version 1.0.
40 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
42 * \brief Tests for C++14-compatible implementation of std::string_view.
44 * These tests are similer to those used in commit bf5824916b6895ccab0dbc2431520ee3b6d4f27f of
45 * https://github.com/martinmoene/string_view-lite.git. The code has not
46 * been linted with uncrustify so that any future updates to this
47 * active repo can be incorporated easily, and //NOLINT comments added
48 * to suppress clang-tidy warnings. The form of those
49 * changes have been made to simplify the contents, while making it
50 * easy to import any bug fixes that may appear in the source
53 * \todo Remove when requiring C++17, which has a standardized version
54 * of std::string_view.
56 * \author Paul Bauer <paul.bauer.q@gmail.com>
57 * \ingroup module_compat
61 #include "gromacs/compat/string_view.h"
63 #include <initializer_list>
69 #include <gtest/gtest.h>
71 #include "gromacs/utility/strconvert.h"
73 // GMX modification to suppress Doxygen checking
79 using namespace compat
;
84 T
* data( std::vector
<T
> & v
)
86 #if nssv_CPP11_OR_GREATER
93 #define nssv_STD_SV_OR( expr ) ( nssv_USES_STD_STRING_VIEW || (expr) )
95 typedef string_view::size_type size_type
;
97 // 24.4.2.1 Construction and assignment:
99 TEST(StringViewTest
, CanDefaultConstructEmptyView
)
101 SCOPED_TRACE( "string_view: Allows to default construct an empty string_view" );
105 // use parenthesis with data() to prevent lest from using sv.data() as C-string:
107 EXPECT_TRUE( sv
.size() == size_type( 0 ) );
108 EXPECT_TRUE( (sv
.data() == nssv_nullptr
) );
111 TEST(StringViewTest
, CanConstructFromPointerAndSize
)
113 SCOPED_TRACE( "string_view: Allows to construct from pointer and size" );
115 string_view
sv( "hello world", 5 );
117 EXPECT_TRUE( sv
.size() == size_type( 5 ) );
118 EXPECT_TRUE( *(sv
.data() + 0) == 'h' );
119 EXPECT_TRUE( *(sv
.data() + 4) == 'o' );
122 TEST(StringViewTest
, CanConstructFromCString
)
124 SCOPED_TRACE( "string_view: Allows to construct from C-string" );
126 string_view
sv( "hello world" );
128 EXPECT_TRUE( sv
.size() == size_type( 11 ) );
129 EXPECT_TRUE( *(sv
.data() + 0) == 'h' );
130 EXPECT_TRUE( *(sv
.data() + 10) == 'd' );
133 TEST(StringViewTest
, CanCopyConstructFromEmptyView
)
135 SCOPED_TRACE( "string_view: Allows to copy-construct from empty string_view" );
139 string_view
sv2( sv1
);
141 // use parenthesis with data() to prevent lest from using sv.data() as C-string:
143 EXPECT_TRUE( sv2
.size() == size_type( 0 ) );
144 EXPECT_TRUE( (sv2
.data() == nssv_nullptr
) );
147 TEST(StringViewTest
, CanCopyConstructFromNonEmptyView
)
149 SCOPED_TRACE( "string_view: Allows to copy-construct from non-empty string_view" );
151 string_view
sv1( "hello world", 5 );
153 string_view
sv2( sv1
);
155 EXPECT_TRUE( sv2
.size() == sv1
.size() );
156 EXPECT_TRUE( (sv2
.data() == sv1
.data()) );
157 EXPECT_TRUE( *(sv2
.data() + 0) == 'h' );
158 EXPECT_TRUE( *(sv2
.data() + 4) == 'o' );
163 TEST(StringViewTest
, CanCopyAssingFromEmptyView
)
165 SCOPED_TRACE( "string_view: Allows to copy-assign from empty string_view" );
172 // use parenthesis with data() to prevent lest from using sv.data() as C-string:
174 EXPECT_TRUE( sv2
.size() == size_type( 0 ) );
175 EXPECT_TRUE( (sv2
.data() == nssv_nullptr
) );
178 TEST(StringViewTest
, CanCopyAssingFromNonEmptyView
)
180 SCOPED_TRACE( "string_view: Allows to copy-assign from non-empty string_view" );
182 string_view
sv1( "hello world", 5 );
187 // use parenthesis with data() to prevent lest from using sv.data() as C-string:
189 EXPECT_TRUE( sv2
.size() == sv1
.size() );
190 EXPECT_TRUE( (sv2
.data() == sv1
.data()) );
191 EXPECT_TRUE( *(sv2
.data() + 0) == 'h' );
192 EXPECT_TRUE( *(sv2
.data() + 4) == 'o' );
195 // 24.4.2.2 Iterator support:
197 TEST(StringViewTest
, AllowForwardIteration
)
199 SCOPED_TRACE( "string_view: Allows forward iteration" );
201 char hello
[] = "hello";
202 string_view
sv( hello
);
204 for ( string_view::iterator pos
= sv
.begin(); pos
!= sv
.end(); ++pos
)
206 typedef std::iterator_traits
< string_view::iterator
>::difference_type difference_type
;
208 difference_type i
= std::distance( sv
.begin(), pos
);
209 EXPECT_TRUE( *pos
== *(sv
.data() + i
) );
213 TEST(StringViewTest
, AllowConstForwardIteration
)
215 SCOPED_TRACE( "string_view: Allows const forward iteration" );
217 char hello
[] = "hello";
218 string_view
sv( hello
);
220 for ( string_view::const_iterator pos
= sv
.begin(); pos
!= sv
.end(); ++pos
)
222 typedef std::iterator_traits
< string_view::const_iterator
>::difference_type difference_type
;
224 difference_type i
= std::distance( sv
.cbegin(), pos
);
225 EXPECT_TRUE( *pos
== *(sv
.data() + i
) );
229 TEST(StringViewTest
, AllowReverseIteration
)
231 SCOPED_TRACE( "string_view: Allows reverse iteration" );
233 char hello
[] = "hello";
234 string_view
sv( hello
);
236 for ( string_view::reverse_iterator pos
= sv
.rbegin(); pos
!= sv
.rend(); ++pos
)
238 typedef std::iterator_traits
< string_view::reverse_iterator
>::difference_type difference_type
;
240 difference_type dist
= std::distance( sv
.rbegin(), pos
);
241 EXPECT_TRUE( *pos
== *(sv
.data() + sv
.size() - 1 - dist
) );
245 TEST(StringViewTest
, AllowConstReverseIteration
)
247 SCOPED_TRACE( "string_view: Allows const reverse iteration" );
249 char hello
[] = "hello";
250 string_view
sv( hello
);
252 for ( string_view::const_reverse_iterator pos
= sv
.crbegin(); pos
!= sv
.crend(); ++pos
)
254 typedef std::iterator_traits
< string_view::const_reverse_iterator
>::difference_type difference_type
;
256 difference_type dist
= std::distance( sv
.crbegin(), pos
);
257 EXPECT_TRUE( *pos
== *(sv
.data() + sv
.size() - 1 - dist
) );
261 // 24.4.2.3 Capacity:
263 TEST(StringViewTest
, CanObtainSizeFromViewViaSize
)
265 SCOPED_TRACE( "string_view: Allows to obtain the size of the view via size()" );
267 char hello
[] = "hello";
268 string_view
sv( hello
);
270 EXPECT_TRUE( sv
.size() == std::char_traits
<char>::length(hello
) );
273 TEST(StringViewTest
, CanObtainSizeFromViewViaLength
)
275 SCOPED_TRACE( "string_view: Allows to obtain the size of the view via length()" );
277 char hello
[] = "hello";
278 string_view
sv( hello
);
280 EXPECT_TRUE( sv
.length() == std::char_traits
<char>::length(hello
) );
283 TEST(StringViewTest
, CanObtainMaxSizeViaMaxSize
)
285 SCOPED_TRACE( "string_view: Allows to obtain the maximum size a view can be via max_size()" );
288 EXPECT_TRUE( string_view().max_size() >= (std::numeric_limits
< string_view::size_type
>::max
)() / 10 );
291 TEST(StringViewTest
, CanCheckForEmptyStringWithEmpty
)
293 SCOPED_TRACE( "string_view: Allows to check for an empty string_view via empty()" );
296 string_view
svne("hello");
298 EXPECT_TRUE( sve
.size() == size_type( 0 ) );
299 EXPECT_TRUE( sve
.empty() );
300 EXPECT_FALSE( svne
.empty() );
303 // 24.4.2.4 Element access:
305 TEST(StringViewTest
, CanAccessElementViaArrayIndex
)
307 SCOPED_TRACE( "string_view: Allows to observe an element via array indexing" );
309 // Requires: index < sv.size()
311 char hello
[] = "hello";
312 string_view
sv( hello
);
314 for ( size_type i
= 0; i
< sv
.size(); ++i
)
316 EXPECT_TRUE( sv
[i
] == hello
[i
] );
320 TEST(StringViewTest
, CanAccessElementViaAt
)
322 SCOPED_TRACE( "string_view: Allows to observe an element via at()" );
324 char hello
[] = "hello";
325 string_view
sv( hello
);
327 for ( size_type i
= 0; i
< sv
.size(); ++i
)
329 EXPECT_TRUE( sv
.at(i
) == hello
[i
] );
333 TEST(StringViewTest
, ThrowsOnOutOfBoundsAccess
)
335 SCOPED_TRACE( "string_view: Throws at observing an element via at() with an index of size() or larger" );
337 string_view
sv("hello");
339 EXPECT_ANY_THROW( sv
.at( sv
.size() ) );
340 EXPECT_NO_THROW( sv
.at( sv
.size() - 1 ) );
343 TEST(StringViewTest
, CanAccessAllElementsViaData
)
345 SCOPED_TRACE( "string_view: Allows to observe elements via data()" );
347 char hello
[] = "hello";
348 string_view
sv( hello
);
350 EXPECT_TRUE( *sv
.data() == *sv
.begin() );
352 for ( size_type i
= 0; i
< sv
.size(); ++i
)
354 EXPECT_TRUE( sv
.data()[i
] == hello
[i
] );
358 TEST(StringViewTest
, DataFromEmptyStringIsNullptr
)
360 SCOPED_TRACE( "string_view: Yields nullptr (or NULL) with data() for an empty string_view" );
364 // use parenthesis with data() to prevent lest from using sv.data() as C-string:
366 EXPECT_TRUE( (sv
.data() == nssv_nullptr
) );
369 // 24.4.2.5 Modifiers:
371 TEST(StringViewTest
, CanRemovePrefix
)
373 SCOPED_TRACE( "string_view: Allows to remove a prefix of n elements" );
375 char hello
[] = "hello world";
376 string_view
sv( hello
);
378 sv
.remove_prefix( 6 );
380 EXPECT_TRUE( sv
.size() == size_type( 5 ) );
381 EXPECT_TRUE( std::equal( sv
.begin(), sv
.end(), hello
+ 6) );
384 TEST(StringViewTest
, CanRemoveSuffix
)
386 SCOPED_TRACE( "string_view: Allows to remove a suffix of n elements" );
388 char hello
[] = "hello world";
389 string_view
sv( hello
);
391 sv
.remove_suffix( 6 );
393 EXPECT_TRUE( sv
.size() == size_type( 5 ) );
394 EXPECT_TRUE( std::equal( sv
.begin(), sv
.end(), hello
) );
397 TEST(StringViewTest
, CanSwapWithOtherView
)
399 SCOPED_TRACE( "string_view: Allows to swap with other string_view" );
401 char hello
[] = "hello";
402 char world
[] = "world";
403 string_view
sv1( hello
);
404 string_view
sv2( world
);
408 EXPECT_TRUE( std::equal( sv1
.begin(), sv1
.end(), world
) );
409 EXPECT_TRUE( std::equal( sv2
.begin(), sv2
.end(), hello
) );
412 // 24.4.2.6 String operations:
414 TEST(StringViewTest
, CanCopySubstringWithCopy
)
416 SCOPED_TRACE( "string_view: Allows to copy a substring of length n, starting at position pos (default: 0) via copy()" );
418 char hello
[] = "hello world";
419 string_view
sv( hello
);
422 std::vector
<string_view::value_type
> vec( sv
.size() );
424 sv
.copy( data(vec
), vec
.size() );
426 EXPECT_TRUE( std::equal( vec
.begin(), vec
.end(), hello
) );
428 std::size_t offset
= 3U; std::size_t length
= 4U;
429 std::vector
<string_view::value_type
> vec( length
);
431 sv
.copy( data(vec
), length
, offset
);
433 EXPECT_TRUE( std::equal( vec
.begin(), vec
.end(), hello
+ offset
) );
437 TEST(StringViewTest
, ThrowsOnOutOfBoundsCopy
)
439 SCOPED_TRACE( "string_view: Throws if requested position of copy() exceeds string_view's size()" );
441 string_view
sv("hello world");
442 std::vector
<string_view::value_type
> vec( sv
.size() );
444 EXPECT_ANY_THROW( sv
.copy( data(vec
), sv
.size() - 4, sv
.size() + 1 ) );
445 EXPECT_NO_THROW( sv
.copy( data(vec
), sv
.size() - 4, sv
.size() + 0 ) );
448 TEST(StringViewTest
, CanObtainSubstringWithSubstr
)
450 SCOPED_TRACE( "string_view: Allow to obtain a sub string, starting at position pos (default: 0) and of length n (default full), via substr()" );
452 char hello
[] = "hello world";
453 string_view
sv( hello
);
456 #if nssv_USES_STD_STRING_VIEW && defined(__GNUC__)
457 EXPECT_TRUE( !!"std::string_view::substr(), with default pos, count is not available with GNU C" );
459 EXPECT_TRUE( std::equal( sv
.begin(), sv
.end(), sv
.substr().begin() ) );
462 string_view subv
= sv
.substr( 6 );
464 EXPECT_TRUE( std::equal( subv
.begin(), subv
.end(), hello
+ 6 ) );
466 string_view subv
= sv
.substr( 3, 4 );
468 EXPECT_TRUE( std::equal( subv
.begin(), subv
.end(), hello
+ 3 ) );
472 TEST(StringViewTest
, ThrowsOnOutOfBoundsSubstr
)
474 SCOPED_TRACE( "string_view: Throws if requested position of substr() exceeds string_view's size()" );
476 string_view
sv("hello world");
478 EXPECT_ANY_THROW( sv
.substr( sv
.size() + 1 ) );
479 EXPECT_NO_THROW( sv
.substr( sv
.size() + 0 ) );
482 TEST(StringViewTest
, CanLexicallyCompareViewWithCompare
)
484 SCOPED_TRACE( "string_view: Allows to lexically compare to another string_view via compare(), (1)" );
486 char hello
[] = "hello";
487 char world
[] = "world";
489 EXPECT_TRUE( string_view( hello
).compare( string_view( hello
) ) == 0 );
490 EXPECT_TRUE( string_view( hello
).compare( string_view( world
) ) < 0 );
491 EXPECT_TRUE( string_view( world
).compare( string_view( hello
) ) > 0 );
493 char hello_sp
[] = "hello ";
495 EXPECT_TRUE( string_view( hello
).compare( string_view( hello_sp
) ) < 0 );
496 EXPECT_TRUE( string_view( hello_sp
).compare( string_view( hello
) ) > 0 );
499 TEST(StringViewTest
, CanCompareEmptyViewsWIthCompare
)
501 SCOPED_TRACE( "string_view: Allows to compare empty string_views as equal via compare(), (1)" );
503 EXPECT_TRUE( string_view().compare( string_view() ) == 0 );
506 TEST(StringViewTest
, CanCompareSubStringWithViewViaCompare
)
508 SCOPED_TRACE( "string_view: Allows to compare a sub string to another string_view via compare(), (2)" );
510 string_view
sv1("hello world");
511 string_view
sv2("world");
513 EXPECT_TRUE( sv1
.compare ( 0, sv1
.length(), sv1
) == 0 );
514 EXPECT_TRUE( sv1
.compare ( 6, 5, sv2
) == 0 );
515 EXPECT_TRUE( sv1
.compare ( 0, 5, sv2
) < 0 );
516 EXPECT_TRUE( sv2
.compare ( 0, 5, sv1
) > 0 );
519 TEST(StringViewTest
, CanCompareSubStringWithSubStringViewViaCompare
)
521 SCOPED_TRACE( "string_view: Allows to compare a sub string to another string_view sub string via compare(), (3)" );
523 string_view
sv1("hello world");
525 EXPECT_TRUE( sv1
.compare ( 0, sv1
.length(), sv1
) == 0 );
526 EXPECT_TRUE( sv1
.compare ( 6, 5, sv1
, 6, 5 ) == 0 );
527 EXPECT_TRUE( sv1
.compare ( 0, 5, sv1
, 6, 5 ) < 0 );
528 EXPECT_TRUE( sv1
.compare ( 6, 5, sv1
, 0, 5 ) > 0 );
531 TEST(StringViewTest
, CanCompareToCStringViaCompare
)
533 SCOPED_TRACE( "string_view: Allows to compare to a C-string via compare(), (4)" );
535 char hello
[] = "hello";
536 char world
[] = "world";
538 EXPECT_TRUE( string_view( hello
).compare( hello
) == 0 );
539 EXPECT_TRUE( string_view( hello
).compare( world
) < 0 );
540 EXPECT_TRUE( string_view( world
).compare( hello
) > 0 );
543 TEST(StringViewTest
, CanCompareSubStringToCStringViaCompare
)
545 SCOPED_TRACE( "string_view: Allows to compare a sub string to a C-string via compare(), (5)" );
547 char hello
[] = "hello world";
548 char world
[] = "world";
550 EXPECT_TRUE( string_view( hello
).compare( 6, 5, world
) == 0 );
551 EXPECT_TRUE( string_view( hello
).compare( world
) < 0 );
552 EXPECT_TRUE( string_view( world
).compare( hello
) > 0 );
555 TEST(StringViewTest
, CanCompareSubStringToCStringPrefixViaCompare
)
557 SCOPED_TRACE( "string_view: Allows to compare a sub string to a C-string prefix via compare(), (6)" );
559 char hello
[] = "hello world";
560 char world
[] = "world";
562 EXPECT_TRUE( string_view( hello
).compare( 6, 5, world
, 5 ) == 0 );
563 EXPECT_TRUE( string_view( hello
).compare( 0, 5, world
, 5 ) < 0 );
564 EXPECT_TRUE( string_view( hello
).compare( 6, 5, hello
, 5 ) > 0 );
567 // 24.4.2.7 Searching:
569 #if nssv_HAVE_STARTS_WITH
571 TEST(StringViewTest
, CanCheckForPrefixViewViaStartsWith
)
573 SCOPED_TRACE( "string_view: Allows to check for a prefix string_view via starts_with(), (1)" );
575 char hello
[] = "hello world";
577 EXPECT_TRUE( string_view( hello
).starts_with( string_view( hello
) ) );
578 EXPECT_TRUE( string_view( hello
).starts_with( string_view("hello") ) );
579 EXPECT_FALSE( string_view( hello
).starts_with( string_view("world") ) );
582 TEST(StringViewTest
, CanCheckForPrefixCharacterViaStartsWith
)
584 SCOPED_TRACE( "string_view: Allows to check for a prefix character via starts_with(), (2)" );
586 char hello
[] = "hello world";
588 EXPECT_TRUE( string_view( hello
).starts_with( 'h' ) );
589 EXPECT_FALSE( string_view( hello
).starts_with( 'e' ) );
592 TEST(StringViewTest
, CanCheckForPrefixCStringViaStartsWith
)
594 SCOPED_TRACE( "string_view: Allows to check for a prefix C-string via starts_with(), (3)" );
596 char hello
[] = "hello world";
598 EXPECT_TRUE( string_view( hello
).starts_with( hello
) );
599 EXPECT_TRUE( string_view( hello
).starts_with("hello") );
600 EXPECT_FALSE( string_view( hello
).starts_with("world") );
603 #endif // nssv_HAVE_STARTS_WITH
605 #if nssv_HAVE_ENDS_WITH
607 TEST(StringViewTest
, CanCheckForSuffixViewViaEndsWith
)
609 SCOPED_TRACE( "string_view: Allows to check for a suffix string_view via ends_with(), (1)" );
611 char hello
[] = "hello world";
613 EXPECT_TRUE( string_view( hello
).ends_with( string_view( hello
) ) );
614 EXPECT_TRUE( string_view( hello
).ends_with( string_view("world") ) );
615 EXPECT_FALSE( string_view( hello
).ends_with( string_view("hello") ) );
618 TEST(StringViewTest
, CanCheckForSuffixCharacterViaEndsWith
)
620 SCOPED_TRACE( "string_view: Allows to check for a suffix character via ends_with(), (2)" );
622 char hello
[] = "hello world";
624 EXPECT_TRUE( string_view( hello
).ends_with( 'd' ) );
625 EXPECT_FALSE( string_view( hello
).ends_with( 'l' ) );
628 TEST(StringViewTest
, CanCheckForSuffixCStringViaEndsWith
)
630 SCOPED_TRACE( "string_view: Allows to check for a suffix C-string via ends_with(), (3)" );
632 char hello
[] = "hello world";
634 EXPECT_TRUE( string_view( hello
).ends_with( hello
) );
635 EXPECT_TRUE( string_view( hello
).ends_with("world") );
636 EXPECT_FALSE( string_view( hello
).ends_with("hello") );
639 #endif // nssv_HAVE_ENDS_WITH
641 TEST(StringViewTest
, CanSearchForViewSubstrViaFind
)
643 SCOPED_TRACE( "string_view: Allows to search for a string_view substring, starting at position pos (default: 0) via find(), (1)" );
645 char hello
[] = "hello world";
646 string_view
sv( hello
);
648 EXPECT_TRUE( sv
.find( sv
) == size_type( 0 ) );
649 EXPECT_TRUE( sv
.find( sv
, 1 ) == string_view::npos
);
650 EXPECT_TRUE( sv
.find( string_view("world" ) ) == size_type( 6 ) );
651 EXPECT_TRUE( sv
.find( string_view("world" ), 6 ) == size_type( 6 ) );
652 EXPECT_TRUE( sv
.find( string_view("world" ), 7 ) == string_view::npos
);
655 TEST(StringViewTest
, CanSearchForCharacterViaFind
)
657 SCOPED_TRACE( "string_view: Allows to search for a character, starting at position pos (default: 0) via find(), (2)" );
659 char hello
[] = "hello world";
660 string_view
sv( hello
);
662 EXPECT_TRUE( sv
.find('h' ) == size_type( 0 ) );
663 EXPECT_TRUE( sv
.find('h', 1 ) == string_view::npos
);
664 EXPECT_TRUE( sv
.find('w' ) == size_type( 6 ) );
665 EXPECT_TRUE( sv
.find('w', 6 ) == size_type( 6 ) );
666 EXPECT_TRUE( sv
.find('w', 7 ) == string_view::npos
);
669 TEST(StringViewTest
, CanSearchForCStringSubstringViaFind
)
671 SCOPED_TRACE( "string_view: Allows to search for a C-string substring, starting at position pos and of length n via find(), (3)" );
673 char hello
[] = "hello world";
674 string_view
sv( hello
);
676 EXPECT_TRUE( sv
.find( hello
, 0, sv
.size() ) == size_type( 0 ) );
677 EXPECT_TRUE( sv
.find( hello
, 1, sv
.size() ) == string_view::npos
);
678 EXPECT_TRUE( sv
.find("world", 0, 5 ) == size_type( 6 ) );
679 EXPECT_TRUE( sv
.find("world", 6, 5 ) == size_type( 6 ) );
680 EXPECT_TRUE( sv
.find("world", 7, 4 ) == string_view::npos
);
681 EXPECT_TRUE( sv
.find("world", 3, 0 ) == size_type( 3 ) );
684 TEST(StringViewTest
, CanSearchForCStringSubstringViaFindWithDefaultPos
)
686 SCOPED_TRACE( "string_view: Allows to search for a C-string substring, starting at position pos (default: 0) via find(), (4)" );
688 char hello
[] = "hello world";
689 string_view
sv( hello
);
691 EXPECT_TRUE( sv
.find( hello
) == size_type( 0 ) );
692 EXPECT_TRUE( sv
.find( hello
, 1 ) == string_view::npos
);
693 EXPECT_TRUE( sv
.find("world" ) == size_type( 6 ) );
694 EXPECT_TRUE( sv
.find("world", 6 ) == size_type( 6 ) );
695 EXPECT_TRUE( sv
.find("world", 7 ) == string_view::npos
);
698 TEST(StringViewTest
, CanBackwardsSearchForViewSubstrViaFind
)
700 SCOPED_TRACE( "string_view: Allows to search backwards for a string_view substring, starting at position pos (default: npos) via rfind(), (1)" );
702 char hello
[] = "hello world";
703 string_view
sv( hello
);
705 EXPECT_TRUE( sv
.rfind( sv
) == size_type( 0 ) );
706 EXPECT_TRUE( sv
.rfind( sv
, 3 ) == size_type( 0 ) );
707 EXPECT_TRUE( sv
.rfind( string_view( ) ) == size_type(11 ) );
708 EXPECT_TRUE( sv
.rfind( string_view("world" ) ) == size_type( 6 ) );
709 EXPECT_TRUE( sv
.rfind( string_view("world" ), 6 ) == size_type( 6 ) );
710 EXPECT_TRUE( sv
.rfind( string_view("world" ), 5 ) == string_view::npos
);
711 EXPECT_TRUE( sv
.rfind( string_view("hello world, a longer text" ) ) == string_view::npos
);
714 TEST(StringViewTest
, CanBackwardsSearchForCharacterViaFind
)
716 SCOPED_TRACE( "string_view: Allows to search backwards for a character, starting at position pos (default: npos) via rfind(), (2)" );
718 char hello
[] = "hello world";
719 string_view
sv( hello
);
721 EXPECT_TRUE( sv
.rfind('h' ) == size_type( 0 ) );
722 EXPECT_TRUE( sv
.rfind('e' ) == size_type( 1 ) );
723 EXPECT_TRUE( sv
.rfind('e', 0 ) == string_view::npos
);
724 EXPECT_TRUE( sv
.rfind('w' ) == size_type( 6 ) );
725 EXPECT_TRUE( sv
.rfind('w', 6 ) == size_type( 6 ) );
726 EXPECT_TRUE( sv
.rfind('w', 5 ) == string_view::npos
);
729 TEST(StringViewTest
, CanBackwardsSearchForCStringSubstringViaFind
)
731 SCOPED_TRACE( "string_view: Allows to search backwards for a C-string substring, starting at position pos and of length n via rfind(), (3)" );
733 char hello
[] = "hello world";
734 string_view
sv( hello
);
736 EXPECT_TRUE( sv
.rfind( hello
) == size_type( 0 ) );
737 EXPECT_TRUE( sv
.rfind( hello
, 0, 5 ) == size_type( 0 ) );
738 EXPECT_TRUE( sv
.rfind( hello
, 1, 5 ) == size_type( 0 ) );
739 EXPECT_TRUE( sv
.rfind("world", 10, 5 ) == size_type( 6 ) );
740 EXPECT_TRUE( sv
.rfind("world", 6, 5 ) == size_type( 6 ) );
741 EXPECT_TRUE( sv
.rfind("world", 5, 5 ) == string_view::npos
);
744 TEST(StringViewTest
, CanBackwardsSearchForCStringSubstringViaFindWithDefaultPos
)
746 SCOPED_TRACE( "string_view: Allows to search backwards for a C-string substring, starting at position pos (default: 0) via rfind(), (4)" );
748 char hello
[] = "hello world";
749 string_view
sv( hello
);
751 EXPECT_TRUE( sv
.rfind( hello
) == size_type( 0 ) );
752 EXPECT_TRUE( sv
.rfind( hello
, 3 ) == size_type( 0 ) );
753 EXPECT_TRUE( sv
.rfind("world" ) == size_type( 6 ) );
754 EXPECT_TRUE( sv
.rfind("world", 6 ) == size_type( 6 ) );
755 EXPECT_TRUE( sv
.rfind("world", 5 ) == string_view::npos
);
758 TEST(StringViewTest
, CanSearchForFirstOccurenceOfAnyCharacterInView
)
760 SCOPED_TRACE( "string_view: Allows to search for the first occurrence of any of the characters specified in a string view, starting at position pos (default: 0) via find_first_of(), (1)" );
762 char hello
[] = "hello world";
763 string_view
sv( hello
);
765 EXPECT_TRUE( sv
.find_first_of( sv
) == size_type( 0 ) );
766 EXPECT_TRUE( sv
.find_first_of( sv
, 3 ) == size_type( 3 ) );
767 EXPECT_TRUE( sv
.find_first_of( string_view("xwo" ) ) == size_type( 4 ) );
768 EXPECT_TRUE( sv
.find_first_of( string_view("wdx" ), 6 ) == size_type( 6 ) );
769 EXPECT_TRUE( sv
.find_first_of( string_view("wxy" ), 7 ) == string_view::npos
);
772 TEST(StringViewTest
, CanSearchForFirstOccurenceOfCharacter
)
774 SCOPED_TRACE( "string_view: Allows to search for a character, starting at position pos (default: 0) via find_first_of(), (2)" );
776 char hello
[] = "hello world";
777 string_view
sv( hello
);
779 EXPECT_TRUE( sv
.find_first_of('h' ) == size_type( 0 ) );
780 EXPECT_TRUE( sv
.find_first_of('h', 1 ) == string_view::npos
);
781 EXPECT_TRUE( sv
.find_first_of('w' ) == size_type( 6 ) );
782 EXPECT_TRUE( sv
.find_first_of('w', 6 ) == size_type( 6 ) );
783 EXPECT_TRUE( sv
.find_first_of('w', 7 ) == string_view::npos
);
786 TEST(StringViewTest
, CanSearchForFirstOccurenceOfCharactersInCStringInLenght
)
788 SCOPED_TRACE( "string_view: Allows to search for the first occurrence of any of the characters specified in a C-string, starting at position pos and of length n via find_first_of(), (3)" );
790 char hello
[] = "hello world";
791 string_view
sv( hello
);
793 EXPECT_TRUE( sv
.find_first_of( hello
, 0, sv
.size() ) == size_type( 0 ) );
794 EXPECT_TRUE( sv
.find_first_of( hello
, 1, sv
.size() ) == size_type( 1 ) );
795 EXPECT_TRUE( sv
.find_first_of( "xwy", 0, 3 ) == size_type( 6 ) );
796 EXPECT_TRUE( sv
.find_first_of( "xwy", 6, 3 ) == size_type( 6 ) );
797 EXPECT_TRUE( sv
.find_first_of( "xwy", 7, 3 ) == string_view::npos
);
798 EXPECT_TRUE( sv
.find_first_of( "xyw", 0, 2 ) == string_view::npos
);
801 TEST(StringViewTest
, CanSearchForFirstOccurenceOfCharactersInCString
)
803 SCOPED_TRACE( "string_view: Allows to search for the first occurrence of any of the characters specified in a C-string, starting at position pos via find_first_of(), (4)" );
805 char hello
[] = "hello world";
806 string_view
sv( hello
);
808 EXPECT_TRUE( sv
.find_first_of( hello
, 0 ) == size_type( 0 ) );
809 EXPECT_TRUE( sv
.find_first_of( hello
, 1 ) == size_type( 1 ) );
810 EXPECT_TRUE( sv
.find_first_of( "xwy", 0 ) == size_type( 6 ) );
811 EXPECT_TRUE( sv
.find_first_of( "xwy", 6 ) == size_type( 6 ) );
812 EXPECT_TRUE( sv
.find_first_of( "xwy", 7 ) == string_view::npos
);
815 TEST(StringViewTest
, CanBackwardsSearchForLastOccurenceOfAnyCharacterInView
)
817 SCOPED_TRACE( "string_view: Allows to search backwards for the last occurrence of any of the characters specified in a string view, starting at position pos (default: npos) via find_last_of(), (1)" );
819 char hello
[] = "hello world";
821 string_view
sv( hello
);
822 string_view
sve( empty
);
824 EXPECT_TRUE( sv
.find_last_of( sv
) == size_type( 10 ) );
825 EXPECT_TRUE( sv
.find_last_of( sv
, 3 ) == size_type( 3 ) );
826 EXPECT_TRUE( sv
.find_last_of( string_view("xwo" ) ) == size_type( 7 ) );
827 EXPECT_TRUE( sv
.find_last_of( string_view("wdx" ), 6 ) == size_type( 6 ) );
828 EXPECT_TRUE( sv
.find_last_of( string_view("wxy" ), 7 ) == size_type( 6 ) );
830 EXPECT_TRUE( sve
.find_last_of( string_view("x") ) == string_view::npos
); // issue 20 (endless loop)
833 TEST(StringViewTest
, CanBackwardsSearchForLastOccurenceOfCharacter
)
835 SCOPED_TRACE( "string_view: Allows to search backwards for a character, starting at position pos (default: 0) via find_last_of(), (2)" );
837 char hello
[] = "hello world";
838 string_view
sv( hello
);
840 EXPECT_TRUE( sv
.find_last_of('h' ) == size_type( 0 ) );
841 EXPECT_TRUE( sv
.find_last_of('l', 1 ) == string_view::npos
);
842 EXPECT_TRUE( sv
.find_last_of('w' ) == size_type( 6 ) );
843 EXPECT_TRUE( sv
.find_last_of('w', 6 ) == size_type( 6 ) );
844 EXPECT_TRUE( sv
.find_last_of('w', 5 ) == string_view::npos
);
847 TEST(StringViewTest
, CanBackwardsSearchForLastOccurenceOfCharactersInCStringInLenght
)
849 SCOPED_TRACE( "string_view: Allows to search backwards for the first occurrence of any of the characters specified in a C-string, starting at position pos and of length n via find_last_of(), (3)" );
851 char hello
[] = "hello world";
852 string_view
sv( hello
);
854 EXPECT_TRUE( sv
.find_last_of( hello
, 0, sv
.size() ) == size_type( 0 ) );
855 EXPECT_TRUE( sv
.find_last_of( hello
, 1, sv
.size() ) == size_type( 1 ) );
856 EXPECT_TRUE( sv
.find_last_of("xwy", 10, 3 ) == size_type( 6 ) );
857 EXPECT_TRUE( sv
.find_last_of("xwy", 6, 3 ) == size_type( 6 ) );
858 EXPECT_TRUE( sv
.find_last_of("xwy", 5, 3 ) == string_view::npos
);
859 EXPECT_TRUE( sv
.find_last_of("xyw", 10, 2 ) == string_view::npos
);
862 TEST(StringViewTest
, CanBackwardsSearchForLastOccurenceOfCharactersInCString
)
864 SCOPED_TRACE( "string_view: Allows to search backwards for the first occurrence of any of the characters specified in a C-string, starting at position pos via find_last_of(), (4)" );
866 char hello
[] = "hello world";
867 string_view
sv( hello
);
869 EXPECT_TRUE( sv
.find_last_of( hello
, 0 ) == size_type( 0 ) );
870 EXPECT_TRUE( sv
.find_last_of( hello
, 1 ) == size_type( 1 ) );
871 EXPECT_TRUE( sv
.find_last_of( "xwy", 10 ) == size_type( 6 ) );
872 EXPECT_TRUE( sv
.find_last_of( "xwy", 6 ) == size_type( 6 ) );
873 EXPECT_TRUE( sv
.find_last_of( "xwy", 5 ) == string_view::npos
);
876 TEST(StringViewTest
, CanSearchForFirstNotFoundCharacter
)
878 SCOPED_TRACE( "string_view: Allows to search for the first character not specified in a string view, starting at position pos (default: 0) via find_first_not_of(), (1)" );
880 char hello
[] = "hello world";
881 string_view
sv( hello
);
883 EXPECT_TRUE( sv
.find_first_not_of( sv
) == string_view::npos
);
884 EXPECT_TRUE( sv
.find_first_not_of( sv
, 3 ) == string_view::npos
);
885 EXPECT_TRUE( sv
.find_first_not_of( string_view("helo " ) ) == size_type( 6 ) );
886 EXPECT_TRUE( sv
.find_first_not_of( string_view("helo " ), 6 ) == size_type( 6 ) );
887 EXPECT_TRUE( sv
.find_first_not_of( string_view("helo " ), 7 ) == size_type( 8 ) );
888 EXPECT_TRUE( sv
.find_first_not_of( string_view("helo wr" ) ) == size_type( 10 ) );
891 TEST(StringViewTest
, CanSearchForFirstNonMatchingCharacter
)
893 SCOPED_TRACE( "string_view: Allows to search for the first character not equal to the specified character, starting at position pos (default: 0) via find_first_not_of(), (2)" );
895 char hello
[] = "hello world";
896 string_view
sv( hello
);
898 EXPECT_TRUE( sv
.find_first_not_of('h' ) == size_type( 1 ) );
899 EXPECT_TRUE( sv
.find_first_not_of('h', 1 ) == size_type( 1 ) );
900 EXPECT_TRUE( sv
.find_first_not_of('w' ) == size_type( 0 ) );
901 EXPECT_TRUE( sv
.find_first_not_of('w', 6 ) == size_type( 7 ) );
902 EXPECT_TRUE( sv
.find_first_not_of('d', 10 ) == string_view::npos
);
905 TEST(StringViewTest
, CanSearchForFirstNonEqualToAnyCharacterInCStringInLength
)
907 SCOPED_TRACE( "string_view: Allows to search for the first character not equal to any of the characters specified in a C-string, starting at position pos and of length n via find_first_not_of(), (3)" );
909 char hello
[] = "hello world";
910 string_view
sv( hello
);
912 EXPECT_TRUE( sv
.find_first_not_of( hello
, 0, sv
.size() ) == string_view::npos
);
913 EXPECT_TRUE( sv
.find_first_not_of( hello
, 3, sv
.size() ) == string_view::npos
);
914 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 0, 5 ) == size_type( 6 ) );
915 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 6, 5 ) == size_type( 6 ) );
916 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 7, 5 ) == size_type( 8 ) );
917 EXPECT_TRUE( sv
.find_first_not_of( "helo wr", 0, 7 ) == size_type( 10 ) );
918 EXPECT_TRUE( sv
.find_first_not_of( "he" , 0, 1 ) == size_type( 1 ) );
921 TEST(StringViewTest
, CanSearchForFirstNonEqualToAnyCharacterInCString
)
923 SCOPED_TRACE( "string_view: Allows to search for the first character not equal to any of the characters specified in a C-string, starting at position pos via find_first_not_of(), (4)" );
925 char hello
[] = "hello world";
926 string_view
sv( hello
);
928 EXPECT_TRUE( sv
.find_first_not_of( hello
, 0 ) == string_view::npos
);
929 EXPECT_TRUE( sv
.find_first_not_of( hello
, 3 ) == string_view::npos
);
930 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 0 ) == size_type( 6 ) );
931 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 6 ) == size_type( 6 ) );
932 EXPECT_TRUE( sv
.find_first_not_of( "helo " , 7 ) == size_type( 8 ) );
933 EXPECT_TRUE( sv
.find_first_not_of( "helo wr", 0 ) == size_type( 10 ) );
936 TEST(StringViewTest
, CanBackwardsSearchForForstNonFoundCharacterInView
)
938 SCOPED_TRACE( "string_view: Allows to search backwards for the first character not specified in a string view, starting at position pos (default: npos) via find_last_not_of(), (1)" );
940 char hello
[] = "hello world";
942 string_view
sv( hello
);
943 string_view
sve( empty
);
945 EXPECT_TRUE( sv
.find_last_not_of( sv
) == string_view::npos
);
946 EXPECT_TRUE( sv
.find_last_not_of( sv
, 3 ) == string_view::npos
);
947 EXPECT_TRUE( sv
.find_last_not_of( string_view("world " ) ) == size_type( 1 ) );
948 EXPECT_TRUE( sv
.find_last_not_of( string_view("heo " ), 4 ) == size_type( 3 ) );
949 EXPECT_TRUE( sv
.find_last_not_of( string_view("heo " ), 3 ) == size_type( 3 ) );
950 EXPECT_TRUE( sv
.find_last_not_of( string_view("heo " ), 2 ) == size_type( 2 ) );
951 EXPECT_TRUE( sv
.find_last_not_of( string_view("x" ) ) == size_type( 10 ) );
953 EXPECT_TRUE( sve
.find_last_not_of( string_view("x") ) == string_view::npos
); // issue 20 (endless loop)
956 TEST(StringViewTest
, CanBackwardsSearchForFirstNonMatchingCharacter
)
958 SCOPED_TRACE( "string_view: Allows to search backwards for the first character not equal to the specified character, starting at position pos (default: npos) via find_last_not_of(), (2)" );
960 char hello
[] = "hello world";
961 string_view
sv( hello
);
963 EXPECT_TRUE( sv
.find_last_not_of('d' ) == size_type( 9 ) );
964 EXPECT_TRUE( sv
.find_last_not_of('d', 10 ) == size_type( 9 ) );
965 EXPECT_TRUE( sv
.find_last_not_of('d', 9 ) == size_type( 9 ) );
966 EXPECT_TRUE( sv
.find_last_not_of('d', 8 ) == size_type( 8 ) );
967 EXPECT_TRUE( sv
.find_last_not_of('d', 0 ) == size_type( 0 ) );
970 TEST(StringViewTest
, CanBackwardsSearchForFirstNonEqualToAnyCharacterInCStringInLength
)
972 SCOPED_TRACE( "string_view: Allows to search backwards for the first character not equal to any of the characters specified in a C-string, starting at position pos and of length n via find_last_not_of(), (3)" );
974 char hello
[] = "hello world";
975 string_view
sv( hello
);
977 EXPECT_TRUE( sv
.find_last_not_of( hello
, 0, sv
.size() ) == string_view::npos
);
978 EXPECT_TRUE( sv
.find_last_not_of( hello
, 3, sv
.size() ) == string_view::npos
);
979 EXPECT_TRUE( sv
.find_last_not_of( "world ", 10, 6 ) == size_type( 1 ) );
980 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 4, 4 ) == size_type( 3 ) );
981 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 3, 4 ) == size_type( 3 ) );
982 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 2, 4 ) == size_type( 2 ) );
983 EXPECT_TRUE( sv
.find_last_not_of( "x" ) == size_type( 10 ) );
986 TEST(StringViewTest
, CanBackwardsSearchForFirstNonEqualToAnyCharacterInCString
)
988 SCOPED_TRACE( "string_view: Allows to search backwards for the first character not equal to any of the characters specified in a C-string, starting at position pos via find_last_not_of(), (4)" );
990 char hello
[] = "hello world";
991 string_view
sv( hello
);
993 EXPECT_TRUE( sv
.find_last_not_of( hello
, 0 ) == string_view::npos
);
994 EXPECT_TRUE( sv
.find_last_not_of( hello
, 3 ) == string_view::npos
);
995 EXPECT_TRUE( sv
.find_last_not_of( "world ", 10 ) == size_type( 1 ) );
996 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 4 ) == size_type( 3 ) );
997 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 3 ) == size_type( 3 ) );
998 EXPECT_TRUE( sv
.find_last_not_of( "heo " , 2 ) == size_type( 2 ) );
999 EXPECT_TRUE( sv
.find_last_not_of( "x" ) == size_type( 10 ) );
1002 TEST(StringViewTest
, CanCreateViewWithLiteralSV
)
1004 SCOPED_TRACE( "string_view: Allows to create a string_view, wstring_view, u16string_view, u32string_view via literal \"sv\"" );
1006 #if nssv_CONFIG_STD_SV_OPERATOR
1007 #if nssv_STD_SV_OR( nssv_HAVE_STD_DEFINED_LITERALS )
1008 using namespace nonstd::literals::string_view_literals
;
1010 string_view sv1
= "abc"sv
;
1011 wstring_view sv2
= L
"abc"sv
;
1013 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1014 EXPECT_TRUE( sv2
.size() == size_type( 3 ) );
1016 #if nssv_HAVE_WCHAR16_T
1017 u16string_view sv3
= u
"abc"sv
;
1018 EXPECT_TRUE( sv3
.size() == size_type( 3 ) );
1020 #if nssv_HAVE_WCHAR32_T
1021 u32string_view sv4
= U
"abc"sv
;
1022 EXPECT_TRUE( sv4
.size() == size_type( 3 ) );
1025 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1028 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1032 TEST(StringViewTest
, CanCreateViewWithLiteralSVInLiteralsStringViewLiteralsNamespace
)
1034 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"sv\", using namespace gmx::compat::literals::string_view_literals" );
1036 #if nssv_CONFIG_STD_SV_OPERATOR
1037 #if nssv_STD_SV_OR( nssv_HAVE_STD_DEFINED_LITERALS )
1038 using namespace gmx::compat::literals::string_view_literals
;
1040 string_view sv1
= "abc\0\0def";
1041 string_view sv2
= "abc\0\0def"sv
;
1043 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1044 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1046 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1049 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1053 TEST(StringViewTest
, CanCreateViewWithLiteralSVInStringViewLiteralsNamespace
)
1055 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"sv\", using namespace gmx::compat::string_view_literals" );
1057 #if nssv_CONFIG_STD_SV_OPERATOR
1058 #if nssv_STD_SV_OR( nssv_HAVE_STD_DEFINED_LITERALS )
1059 #if nssv_STD_SV_OR( nssv_HAVE_INLINE_NAMESPACE )
1060 using namespace gmx::compat::string_view_literals
;
1062 string_view sv1
= "abc\0\0def";
1063 string_view sv2
= "abc\0\0def"sv
;
1065 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1066 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1068 EXPECT_TRUE( !!"Inline namespaces for literal operator 'sv' for string_view not available (no C++11)." );
1071 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1074 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1078 TEST(StringViewTest
, CanCreateViewWithLiteralSVInLiteralsNamespace
)
1080 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"sv\", using namespace gmx::compat::literals" );
1082 #if nssv_CONFIG_STD_SV_OPERATOR
1083 #if nssv_STD_SV_OR( nssv_HAVE_STD_DEFINED_LITERALS )
1084 #if nssv_STD_SV_OR( nssv_HAVE_INLINE_NAMESPACE )
1085 using namespace gmx::compat::literals
;
1087 string_view sv1
= "abc\0\0def";
1088 string_view sv2
= "abc\0\0def"sv
;
1090 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1091 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1093 EXPECT_TRUE( !!"Inline namespaces for literal operator 'sv' for string_view not available (no C++11)." );
1096 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1099 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1103 TEST(StringViewTest
, CanCreateViewWithLiteral_SV
)
1105 SCOPED_TRACE( "string_view: Allows to create a string_view, wstring_view, u16string_view, u32string_view via literal \"_sv\"" );
1107 #if nssv_CONFIG_USR_SV_OPERATOR
1108 #if nssv_STD_SV_OR( nssv_HAVE_USER_DEFINED_LITERALS )
1109 using namespace gmx::compat::literals::string_view_literals
;
1111 string_view sv1
= "abc"_sv
;
1112 wstring_view sv2
= L
"abc"_sv
;
1114 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1115 EXPECT_TRUE( sv2
.size() == size_type( 3 ) );
1117 #if nssv_HAVE_WCHAR16_T
1118 u16string_view sv3
= u
"abc"_sv
;
1119 EXPECT_TRUE( sv3
.size() == size_type( 3 ) );
1121 #if nssv_HAVE_WCHAR32_T
1122 u32string_view sv4
= U
"abc"_sv
;
1123 EXPECT_TRUE( sv4
.size() == size_type( 3 ) );
1126 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1129 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1133 TEST(StringViewTest
, CanCreateViewWithLiteral_SVInLiteralsStringViewLiteralsNamespace
)
1135 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"_sv\", using namespace gmx::compat::literals::string_view_literals" );
1137 #if nssv_CONFIG_USR_SV_OPERATOR
1138 #if nssv_STD_SV_OR( nssv_HAVE_USER_DEFINED_LITERALS )
1139 using namespace gmx::compat::literals::string_view_literals
;
1141 string_view sv1
= "abc\0\0def";
1142 string_view sv2
= "abc\0\0def"_sv
;
1144 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1145 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1147 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1150 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1154 TEST(StringViewTest
, CanCreateViewWithLiteral_SVInStringViewLiteralsNamespace
)
1156 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"_sv\", using namespace gmx::compat::string_view_literals" );
1158 #if nssv_CONFIG_USR_SV_OPERATOR
1159 #if nssv_STD_SV_OR( nssv_HAVE_USER_DEFINED_LITERALS )
1160 #if nssv_STD_SV_OR( nssv_HAVE_INLINE_NAMESPACE )
1161 using namespace gmx::compat::string_view_literals
;
1163 string_view sv1
= "abc\0\0def";
1164 string_view sv2
= "abc\0\0def"_sv
;
1166 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1167 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1169 EXPECT_TRUE( !!"Inline namespaces for literal operator '_sv' for string_view not available (no C++11)." );
1172 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1175 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1179 TEST(StringViewTest
, CanCreateViewWithLiteral_SVInLiteralsNamespace
)
1181 SCOPED_TRACE( "string_view: Allows to create a string_view via literal \"_sv\", using namespace gmx::compat::literals" );
1183 #if nssv_CONFIG_USR_SV_OPERATOR
1184 #if nssv_STD_SV_OR( nssv_HAVE_USER_DEFINED_LITERALS )
1185 #if nssv_STD_SV_OR( nssv_HAVE_INLINE_NAMESPACE )
1186 using namespace gmx::compat::literals
;
1188 string_view sv1
= "abc\0\0def";
1189 string_view sv2
= "abc\0\0def"_sv
;
1191 EXPECT_TRUE( sv1
.size() == size_type( 3 ) );
1192 EXPECT_TRUE( sv2
.size() == size_type( 8 ) );
1194 EXPECT_TRUE( !!"Inline namespaces for literal operator '_sv' for string_view not available (no C++11)." );
1197 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1200 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1204 // 24.4.3 Non-member comparison functions:
1206 TEST(StringViewTest
, CanCompareToViews
)
1208 SCOPED_TRACE( "string_view: Allows to compare a string_view with another string_view" );
1212 string_view
sv( s
);
1213 string_view
tv( t
);
1215 EXPECT_TRUE( sv
.length() == size_type( 5 ) );
1216 EXPECT_TRUE( tv
.length() == size_type( 5 ) );
1218 EXPECT_TRUE( sv
== sv
);
1219 EXPECT_TRUE( sv
!= tv
);
1220 EXPECT_TRUE( sv
<= sv
);
1221 EXPECT_TRUE( sv
<= tv
);
1222 EXPECT_TRUE( sv
< tv
);
1223 EXPECT_TRUE( tv
>= tv
);
1224 EXPECT_TRUE( tv
>= sv
);
1225 EXPECT_TRUE( tv
> sv
);
1228 TEST(StringViewTest
, CanCompareViewToImplicitlyConvertedView
)
1230 SCOPED_TRACE( "string_view: Allows to compare a string_view with an object with implicit conversion to string_view" );
1232 #if nssv_CPP11_OR_GREATER
1233 #if defined(_MSC_VER) && _MSC_VER != 1900
1235 string_view
sv( s
);
1237 EXPECT_TRUE( sv
== "hello" );
1238 EXPECT_TRUE( "hello" == sv
);
1240 EXPECT_TRUE( sv
!= "world" );
1241 EXPECT_TRUE( "world" != sv
);
1243 EXPECT_TRUE( sv
<= "hello" );
1244 EXPECT_TRUE( "hello" <= sv
);
1245 EXPECT_TRUE( sv
<= "world" );
1246 EXPECT_TRUE( "aloha" <= sv
);
1248 EXPECT_TRUE( sv
< "world" );
1249 EXPECT_TRUE( "aloha" < sv
);
1251 EXPECT_TRUE( sv
>= "hello" );
1252 EXPECT_TRUE( "hello" >= sv
);
1253 EXPECT_TRUE( sv
>= "aloha" );
1254 EXPECT_TRUE( "world" >= sv
);
1256 EXPECT_TRUE( sv
> "aloha" );
1257 EXPECT_TRUE( "world" > sv
);
1259 EXPECT_TRUE( !!"Comparison for types with implicit conversion to string_view not available (insufficient C++11 support of MSVC)." );
1262 EXPECT_TRUE( !!"Comparison for types with implicit conversion to string_view not available (no C++11)." );
1266 TEST(StringViewTest
, EmptyViewsCompareAsEqual
)
1268 SCOPED_TRACE( "string_view: Allows to compare empty string_view-s as equal" );
1272 EXPECT_TRUE( a
== b
);
1275 // 24.4.4 Inserters and extractors:
1277 TEST(StringViewTest
, CanPrintViewToPutputStream
)
1279 SCOPED_TRACE ( "operator<<: Allows printing a string_view to an output stream" );
1281 std::ostringstream oss
;
1283 string_view
sv( s
);
1286 << std::right
<< std::setw(10) << sv
<< '\n'
1288 << std::setfill('.') << std::left
<< std::setw(10) << sv
;
1290 EXPECT_TRUE( oss
.str() == "hello\n hello\nhello\nhello....." );
1293 // 24.4.5 Hash support (C++11):
1295 TEST(StringViewTest
, HashOfViewIsEqualToHashOfString
)
1297 SCOPED_TRACE ( "std::hash<>: Hash value of string_view equals hash value of corresponding string object" );
1299 #if nssv_HAVE_STD_HASH
1300 EXPECT_TRUE( std::hash
<string_view
>()( "Hello, world!" ) == std::hash
<std::string
>()( "Hello, world!" ) );
1302 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1306 TEST(StringViewTest
, HashOfWStringViewIsEqualToHashOfString
)
1308 SCOPED_TRACE ( "std::hash<>: Hash value of wstring_view equals hash value of corresponding string object" );
1310 #if nssv_HAVE_STD_HASH
1311 EXPECT_TRUE( std::hash
<wstring_view
>()( L
"Hello, world!" ) == std::hash
<std::wstring
>()( L
"Hello, world!" ) );
1313 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1317 TEST(StringViewTest
, HashOfU16StringViewIsEqualToHashOfString
)
1319 SCOPED_TRACE ( "std::hash<>: Hash value of u16string_view equals hash value of corresponding string object" );
1321 #if nssv_HAVE_STD_HASH
1322 #if nssv_HAVE_WCHAR16_T
1323 #if nssv_HAVE_UNICODE_LITERALS
1324 EXPECT_TRUE( std::hash
<u16string_view
>()( u
"Hello, world!" ) == std::hash
<std::u16string
>()( u
"Hello, world!" ) );
1326 EXPECT_TRUE( !!"Unicode literal u\"...\" is not available (no C++11)" );
1329 EXPECT_TRUE( !!"std::u16string is not available (no C++11)" );
1332 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1336 TEST(StringViewTest
, HashOfU32StringViewIsEqualToHashOfString
)
1338 SCOPED_TRACE ( "std::hash<>: Hash value of u32string_view equals hash value of corresponding string object" );
1340 #if nssv_HAVE_STD_HASH
1341 #if nssv_HAVE_WCHAR16_T
1342 #if nssv_HAVE_UNICODE_LITERALS
1343 EXPECT_TRUE( std::hash
<u32string_view
>()( U
"Hello, world!" ) == std::hash
<std::u32string
>()( U
"Hello, world!" ) );
1345 EXPECT_TRUE( !!"Unicode literal U\"...\" is not available (no C++11)" );
1348 EXPECT_TRUE( !!"std::u32string is not available (no C++11)" );
1351 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1355 // nonstd extension: conversions from and to std::basic_string
1357 TEST(StringViewExtensionTest
, CanConstructViewFromString
)
1359 SCOPED_TRACE( "string_view: construct from std::string " "[extension]" );
1361 #if nssv_USES_STD_STRING_VIEW
1362 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_USES_STD_STRING_VIEW=1)." );
1363 #elif nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1364 char hello
[] = "hello world";
1365 std::string s
= hello
;
1367 string_view
sv( hello
);
1369 EXPECT_TRUE( sv
.size() == s
.size() );
1370 EXPECT_TRUE( sv
.compare( s
) == 0 );
1372 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1376 TEST(StringViewExtensionTest
, CanConvertViewToStringViaExplicitOperator
)
1378 SCOPED_TRACE( "string_view: convert to std::string via explicit operator " "[extension]" );
1380 #if nssv_USES_STD_STRING_VIEW
1381 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_USES_STD_STRING_VIEW=1)." );
1382 #elif nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1383 #if nssv_HAVE_EXPLICIT_CONVERSION
1384 char hello
[] = "hello world";
1385 string_view
sv( hello
);
1387 std::string
s( sv
);
1388 // std::string t{ sv };
1390 EXPECT_TRUE( sv
.size() == s
.size() );
1391 EXPECT_TRUE( sv
.compare( s
) == 0 );
1393 EXPECT_TRUE( !!"explicit conversion is not available (no C++11)." );
1396 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1400 TEST(StringViewExtensionTest
, CanConvertViewToStringViaToString
)
1402 SCOPED_TRACE( "string_view: convert to std::string via to_string() " "[extension]" );
1404 #if nssv_USES_STD_STRING_VIEW
1405 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_USES_STD_STRING_VIEW=1)." );
1406 #elif nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1407 char hello
[] = "hello world";
1408 string_view
sv( hello
);
1410 std::string s1
= sv
.to_string();
1412 EXPECT_TRUE( sv
.size() == s1
.size() );
1413 EXPECT_TRUE( sv
.compare( s1
) == 0 );
1415 std::string s2
= sv
.to_string( std::string::allocator_type() );
1417 EXPECT_TRUE( sv
.size() == s2
.size() );
1418 EXPECT_TRUE( sv
.compare( s2
) == 0 );
1420 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1424 TEST(StringViewExtensionTest
, CanConvertViewToStringViaToStringFreeFunction
)
1426 SCOPED_TRACE( "to_string(): convert to std::string via to_string() " "[extension]" );
1428 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1429 char hello
[] = "hello world";
1430 string_view
sv( hello
);
1432 std::string s1
= to_string( sv
);
1434 EXPECT_TRUE( sv
.size() == s1
.size() );
1435 EXPECT_TRUE( sv
.compare( s1
) == 0 );
1437 std::string s2
= to_string( sv
, std::string::allocator_type() );
1439 EXPECT_TRUE( sv
.size() == s2
.size() );
1440 EXPECT_TRUE( sv
.compare( s2
) == 0 );
1443 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS=0)." );
1447 TEST(StringViewExtensionTest
, CanConvertViewToStringViewViaToStringView
)
1449 SCOPED_TRACE( "to_string_view(): convert from std::string via to_string_view() " "[extension]" );
1451 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1452 char hello
[] = "hello world";
1453 std::string s
= hello
;
1455 string_view sv
= to_string_view( s
);
1457 EXPECT_TRUE( sv
.size() == s
.size() );
1458 EXPECT_TRUE( sv
.compare( s
) == 0 );
1460 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS=0)." );
1464 } // anonymous namespace
1468 // GMX modification to suppress Doxygen checking