Remove unused function generate_excls and make clean_excls static
[gromacs.git] / src / gromacs / compat / tests / string_view.cpp
blob5f5f1b99c073d3a1194dcacd47ecbdb4360558fe
1 /*
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)
41 /*! \internal \file
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
51 * repository.
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
59 #include "gmxpre.h"
61 #include "gromacs/compat/string_view.h"
63 #include <initializer_list>
64 #include <iostream>
65 #include <string>
66 #include <utility>
67 #include <vector>
69 #include <gtest/gtest.h>
71 #include "gromacs/utility/strconvert.h"
73 // GMX modification to suppress Doxygen checking
74 #ifndef DOXYGEN
76 namespace gmx
79 using namespace compat;
81 namespace {
83 template< class T >
84 T * data( std::vector<T> & v )
86 #if nssv_CPP11_OR_GREATER
87 return v.data();
88 #else
89 return &v[0];
90 #endif
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" );
103 string_view sv;
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" );
137 string_view sv1;
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' );
161 // Assignment:
163 TEST(StringViewTest, CanCopyAssingFromEmptyView)
165 SCOPED_TRACE( "string_view: Allows to copy-assign from empty string_view" );
167 string_view sv1;
168 string_view sv2;
170 sv2 = sv1;
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 );
183 string_view sv2;
185 sv2 = sv1;
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()" );
287 // "large"
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()" );
295 string_view sve;
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" );
362 string_view sv;
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 );
406 sv1.swap( sv2 );
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" );
458 #else
459 EXPECT_TRUE( std::equal( sv.begin(), sv.end(), sv.substr().begin() ) );
460 #endif
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";
820 char empty[] = "";
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";
941 char empty[] = "";
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 ) );
1019 #endif
1020 #if nssv_HAVE_WCHAR32_T
1021 u32string_view sv4 = U"abc"sv;
1022 EXPECT_TRUE( sv4.size() == size_type( 3 ) );
1023 #endif
1024 #else
1025 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1026 #endif
1027 #else
1028 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1029 #endif
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 ) );
1045 #else
1046 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1047 #endif
1048 #else
1049 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1050 #endif
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 ) );
1067 #else
1068 EXPECT_TRUE( !!"Inline namespaces for literal operator 'sv' for string_view not available (no C++11)." );
1069 #endif
1070 #else
1071 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1072 #endif
1073 #else
1074 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1075 #endif
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 ) );
1092 #else
1093 EXPECT_TRUE( !!"Inline namespaces for literal operator 'sv' for string_view not available (no C++11)." );
1094 #endif
1095 #else
1096 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (no C++11)." );
1097 #endif
1098 #else
1099 EXPECT_TRUE( !!"Literal operator 'sv' for string_view not available (nssv_CONFIG_STD_SV_OPERATOR=0)." );
1100 #endif
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 ) );
1120 #endif
1121 #if nssv_HAVE_WCHAR32_T
1122 u32string_view sv4 = U"abc"_sv;
1123 EXPECT_TRUE( sv4.size() == size_type( 3 ) );
1124 #endif
1125 #else
1126 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1127 #endif
1128 #else
1129 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1130 #endif
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 ) );
1146 #else
1147 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1148 #endif
1149 #else
1150 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1151 #endif
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 ) );
1168 #else
1169 EXPECT_TRUE( !!"Inline namespaces for literal operator '_sv' for string_view not available (no C++11)." );
1170 #endif
1171 #else
1172 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1173 #endif
1174 #else
1175 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1176 #endif
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 ) );
1193 #else
1194 EXPECT_TRUE( !!"Inline namespaces for literal operator '_sv' for string_view not available (no C++11)." );
1195 #endif
1196 #else
1197 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (no C++11)." );
1198 #endif
1199 #else
1200 EXPECT_TRUE( !!"Literal operator '_sv' for string_view not available (nssv_CONFIG_USR_SV_OPERATOR=0)." );
1201 #endif
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" );
1210 char s[] = "hello";
1211 char t[] = "world";
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
1234 char s[] = "hello";
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 );
1258 #else
1259 EXPECT_TRUE( !!"Comparison for types with implicit conversion to string_view not available (insufficient C++11 support of MSVC)." );
1260 #endif
1261 #else
1262 EXPECT_TRUE( !!"Comparison for types with implicit conversion to string_view not available (no C++11)." );
1263 #endif
1266 TEST(StringViewTest, EmptyViewsCompareAsEqual)
1268 SCOPED_TRACE( "string_view: Allows to compare empty string_view-s as equal" );
1270 string_view a, b;
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;
1282 char s[] = "hello";
1283 string_view sv( s );
1285 oss << sv << '\n'
1286 << std::right << std::setw(10) << sv << '\n'
1287 << 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!" ) );
1301 #else
1302 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1303 #endif
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!" ) );
1312 #else
1313 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1314 #endif
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!" ) );
1325 #else
1326 EXPECT_TRUE( !!"Unicode literal u\"...\" is not available (no C++11)" );
1327 #endif
1328 #else
1329 EXPECT_TRUE( !!"std::u16string is not available (no C++11)" );
1330 #endif
1331 #else
1332 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1333 #endif
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!" ) );
1344 #else
1345 EXPECT_TRUE( !!"Unicode literal U\"...\" is not available (no C++11)" );
1346 #endif
1347 #else
1348 EXPECT_TRUE( !!"std::u32string is not available (no C++11)" );
1349 #endif
1350 #else
1351 EXPECT_TRUE( !!"std::hash is not available (no C++11)" );
1352 #endif
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 );
1371 #else
1372 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1373 #endif
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 );
1392 #else
1393 EXPECT_TRUE( !!"explicit conversion is not available (no C++11)." );
1394 #endif
1395 #else
1396 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1397 #endif
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 );
1419 #else
1420 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS=0)." );
1421 #endif
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 );
1442 #else
1443 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS=0)." );
1444 #endif
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 );
1459 #else
1460 EXPECT_TRUE( !!"Conversion to/from std::string is not available (nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS=0)." );
1461 #endif
1464 } // anonymous namespace
1466 } // namespace gmx
1468 // GMX modification to suppress Doxygen checking
1469 #endif // DOXYGEN