Changeset 4102


Ignore:
Timestamp:
Sep 22, 2021, 9:50:18 AM (8 months ago)
Author:
Peter
Message:

add wrapper function that calls std::string::contains, ::starts_with, and ::ends_with, if available; otherwise use home-brewed code. Add autoconf tests that check if these functions are available in CXX.

Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/configure.ac

    r4094 r4102  
    112112  AC_MSG_FAILURE([$CXX is not a C++11 compiler])
    113113])
     114# test for some features available in modern C++ versions (but not in c++11)
     115YAT_FUNC_STRING_ENDS_WITH
     116YAT_FUNC_STRING_STARTS_WITH
     117YAT_FUNC_STRING_CONTAINS
     118sleep 10
    114119
    115120AC_PROG_SED
  • trunk/test/utility.cc

    r3855 r4102  
    5656void test_inverse(test::Suite&);
    5757
     58void test_contains(test::Suite& suite);
    5859void test_dirname(test::Suite& suite);
     60void test_ends_with(test::Suite& suite);
    5961void test_basename(test::Suite& suite);
    6062void test_fnmatch(test::Suite& suite);
     
    6466void test_rename(test::Suite& suite);
    6567void test_replace(test::Suite& suite);
     68void test_starts_with(test::Suite& suite);
    6669void test_symlink(test::Suite& suite);
    6770
     
    243246  test_symlink(suite);
    244247  test_ticket842(suite);
     248  test_starts_with(suite);
     249  test_contains(suite);
     250  test_ends_with(suite);
    245251
    246252  return suite.return_value();
     
    828834    suite.err() << "incorrect data[1].second: " << data[1].second << "\n";
    829835}
     836
     837
     838void test_starts_with(test::Suite& suite)
     839{
     840  std::string name("Jane Doe");
     841  if (!utility::starts_with(name, "Jane")) {
     842    suite.add(false);
     843    suite.err() << "error: 'Jane Doe' does not start with 'Jane'\n";
     844  }
     845  if (!utility::starts_with(name, 'J')) {
     846    suite.add(false);
     847    suite.err() << "error: starts_with(x,x) failed\n";
     848  }
     849  if (!utility::starts_with(name, name)) {
     850    suite.add(false);
     851    suite.err() << "error: starts_with(x,x) failed\n";
     852  }
     853}
     854
     855
     856void test_contains(test::Suite& suite)
     857{
     858  std::string name("Jane Doe");
     859  if (!utility::contains(name, "ne")) {
     860    suite.add(false);
     861    suite.err() << "error: " << name << " does not contain \"ne\"\n";
     862  }
     863  if (!utility::contains(name, name)) {
     864    suite.add(false);
     865    suite.err() << "error: contains(x,x) failed\n";
     866  }
     867  if (!utility::contains(name, 'D')) {
     868    suite.add(false);
     869    suite.err() << "error: contains(string,char) failed\n";
     870  }
     871}
     872
     873
     874void test_ends_with(test::Suite& suite)
     875{
     876  std::string name("Jane Doe");
     877  if (!utility::ends_with(name, name)) {
     878    suite.add(false);
     879    suite.err() << "error: ends_with(x,x) failed\n";
     880  }
     881  if (!utility::ends_with(name, 'e')) {
     882    suite.add(false);
     883    suite.err() << "error: ends_with(x,x) failed\n";
     884  }
     885  if (!utility::ends_with(name, "Doe")) {
     886    suite.add(false);
     887    suite.err() << "error: 'Jane Doe' does not end with 'Doe'\n";
     888  }
     889}
  • trunk/yat/utility/config_public.h.in

    r3999 r4102  
    4646#undef YAT_HAVE_BOOST_CONCEPT_WITH_CONSTRUCTOR
    4747
     48/* Define if you have function std::string::contains */
     49#undef YAT_HAVE_FUNC_STRING_CONTAINS
     50
     51/* Define if you have function std::string::ends_with */
     52#undef YAT_HAVE_FUNC_STRING_ENDS_WITH
     53
     54/* Define if you have function std::string::starts_with */
     55#undef YAT_HAVE_FUNC_STRING_STARTS_WITH
     56
    4857// macros below are always #defined, and only kept for backward
    4958// compatibility with yat 0.17
  • trunk/yat/utility/utility.h

    r4098 r4102  
    166166
    167167  /**
     168     \return true if string \a str contains \a s
     169
     170     \see https://en.cppreference.com/w/cpp/string/basic_string/comtains
     171
     172     \since New in yat 0.20
     173   */
     174  template<typename charT, class Traits, class Allocator>
     175  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     176                const std::basic_string<charT, Traits, Allocator>& substr);
     177
     178  /// since New in yat 0.20
     179  template<typename charT, class Traits, class Allocator>
     180  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     181                charT substr);
     182
     183  /// since New in yat 0.20
     184  template<typename charT, class Traits, class Allocator>
     185  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     186                const charT* substr);
     187
     188
     189  /**
    168190     \brief convert T to a string
    169191
     
    220242   */
    221243  std::string dirname(const std::string& fn);
     244
     245  /**
     246     \return true if string \a str ends with \a suffix
     247
     248     \see https://en.cppreference.com/w/cpp/string/basic_string/ends_with
     249
     250     \since New in yat 0.20
     251   */
     252  template<typename charT, class Traits, class Allocator>
     253  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     254                 const std::basic_string<charT, Traits, Allocator>& suffix);
     255
     256  /// since New in yat 0.20
     257  template<typename charT, class Traits, class Allocator>
     258  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     259                 charT suffix);
     260
     261  /// since New in yat 0.20
     262  template<typename charT, class Traits, class Allocator>
     263  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     264                 const charT* suffix);
    222265
    223266  /**
     
    451494
    452495  /**
     496     \return true if string \a str starts with \a prefix
     497
     498     \see https://en.cppreference.com/w/cpp/string/basic_string/starts_with
     499
     500     \since New in yat 0.20
     501   */
     502  template<typename charT, class Traits, class Allocator>
     503  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     504                   const std::basic_string<charT, Traits, Allocator>& prefix);
     505
     506  /// since New in yat 0.20
     507  template<typename charT, class Traits, class Allocator>
     508  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     509                   charT prefix);
     510
     511  /// since New in yat 0.20
     512  template<typename charT, class Traits, class Allocator>
     513  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     514                   const charT* prefix);
     515
     516  /**
    453517     Calculate sum of weights in range [first, last). The complexity
    454518     is linear except in the important case when \c Iterator is
     
    570634
    571635
     636  template<typename charT, class Traits, class Allocator>
     637  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     638                const std::basic_string<charT, Traits, Allocator>& substr)
     639  {
     640    return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
     641  }
     642
     643
     644  template<typename charT, class Traits, class Allocator>
     645  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     646                charT substr)
     647  {
     648    return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
     649  }
     650
     651
     652  template<typename charT, class Traits, class Allocator>
     653  bool contains(const std::basic_string<charT, Traits, Allocator>& str,
     654                const charT* substr)
     655  {
     656    return str.find(substr)!=std::basic_string<charT, Traits,Allocator>::npos;
     657  }
     658
     659
    572660  template<typename T>
    573661  std::string convert(T input)
     
    587675                          std::string("\")"));
    588676    return result;
     677  }
     678
     679
     680  template<typename charT, class Traits, class Allocator>
     681  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     682                 const std::basic_string<charT, Traits, Allocator>& suffix)
     683  {
     684#ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
     685    return str.ends_with(suffix);
     686#else
     687    size_t n = suffix.size();
     688    return n <= str.size() && !str.compare(str.size()-n, n, suffix);
     689#endif
     690  }
     691
     692
     693  template<typename charT, class Traits, class Allocator>
     694  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     695                 charT suffix)
     696  {
     697#ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
     698    return str.ends_with(suffix);
     699#else
     700    Traits traits;
     701    return str.size() && traits.eq(str.back(), suffix);
     702#endif
     703  }
     704
     705
     706  template<typename charT, class Traits, class Allocator>
     707  bool ends_with(const std::basic_string<charT, Traits, Allocator>& str,
     708                 const charT* suffix)
     709  {
     710#ifdef YAT_HAVE_FUNC_STRING_ENDS_WITH
     711    return str.ends_with(suffix);
     712#else
     713    Traits traits;
     714    size_t n = traits.length(suffix);
     715    return n <= str.size() && !str.compare(str.size()-n, n, suffix);
     716#endif
    589717  }
    590718
     
    647775      pusher(std::move(element), vec);
    648776    }
     777  }
     778
     779
     780  template<typename charT, class Traits, class Allocator>
     781  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     782                   const std::basic_string<charT, Traits, Allocator>& prefix)
     783  {
     784#ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
     785    return str.starts_with(prefix);
     786#else
     787    size_t n = prefix.size();
     788    return n <= str.size() && !str.compare(0, n, prefix);
     789#endif
     790  }
     791
     792
     793  template<typename charT, class Traits, class Allocator>
     794  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     795                   charT prefix)
     796  {
     797#ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
     798    return str.starts_with(prefix);
     799#else
     800    Traits traits;
     801    return str.size() && traits.eq(str[0], prefix);
     802#endif
     803  }
     804
     805
     806  template<typename charT, class Traits, class Allocator>
     807  bool starts_with(const std::basic_string<charT, Traits, Allocator>& str,
     808                   const charT* prefix)
     809  {
     810#ifdef YAT_HAVE_FUNC_STRING_STARTS_WITH
     811    return str.starts_with(prefix);
     812#else
     813    Traits traits;
     814    size_t n = traits.length(prefix);
     815    return n <= str.size() && !str.compare(0, n, prefix);
     816#endif
    649817  }
    650818
Note: See TracChangeset for help on using the changeset viewer.