1 /*******************************************************************************
2  * tlx/string/ends_with.cpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2007-2019 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #include <tlx/string/ends_with.hpp>
12 
13 #include <algorithm>
14 #include <cstring>
15 
16 #include <tlx/string/to_lower.hpp>
17 
18 namespace tlx {
19 
20 /******************************************************************************/
21 
ends_with(const char * str,const char * match)22 bool ends_with(const char* str, const char* match) {
23     size_t str_size = 0, match_size = 0;
24     while (*str != 0)
25         ++str, ++str_size;
26     while (*match != 0)
27         ++match, ++match_size;
28     if (match_size > str_size)
29         return false;
30 
31     while (match_size != 0) {
32         --str, --match, --match_size;
33         if (*str != *match) return false;
34     }
35     return true;
36 }
37 
ends_with(const char * str,const std::string & match)38 bool ends_with(const char* str, const std::string& match) {
39     size_t str_size = 0, match_size = match.size();
40     while (*str != 0)
41         ++str, ++str_size;
42     if (match_size > str_size)
43         return false;
44 
45     std::string::const_iterator m = match.end();
46     while (m != match.begin()) {
47         --str, --m;
48         if (*str != *m) return false;
49     }
50     return true;
51 }
52 
ends_with(const std::string & str,const char * match)53 bool ends_with(const std::string& str, const char* match) {
54     size_t str_size = str.size(), match_size = strlen(match);
55     if (match_size > str_size)
56         return false;
57 
58     std::string::const_iterator s = str.end() - match_size;
59     while (*match != 0) {
60         if (*s != *match) return false;
61         ++s, ++match;
62     }
63     return true;
64 }
65 
ends_with(const std::string & str,const std::string & match)66 bool ends_with(const std::string& str, const std::string& match) {
67     if (match.size() > str.size())
68         return false;
69 
70     return std::equal(match.begin(), match.end(), str.end() - match.size());
71 }
72 
73 /******************************************************************************/
74 
ends_with_icase(const char * str,const char * match)75 bool ends_with_icase(const char* str, const char* match) {
76     size_t str_size = 0, match_size = 0;
77     while (*str != 0)
78         ++str, ++str_size;
79     while (*match != 0)
80         ++match, ++match_size;
81     if (match_size > str_size)
82         return false;
83 
84     while (match_size != 0) {
85         --str, --match, --match_size;
86         if (to_lower(*str) != to_lower(*match)) return false;
87     }
88     return true;
89 }
90 
ends_with_icase(const char * str,const std::string & match)91 bool ends_with_icase(const char* str, const std::string& match) {
92     size_t str_size = 0, match_size = match.size();
93     while (*str != 0)
94         ++str, ++str_size;
95     if (match_size > str_size)
96         return false;
97 
98     std::string::const_iterator m = match.end();
99     while (m != match.begin()) {
100         --str, --m;
101         if (to_lower(*str) != to_lower(*m)) return false;
102     }
103     return true;
104 }
105 
ends_with_icase(const std::string & str,const char * match)106 bool ends_with_icase(const std::string& str, const char* match) {
107     size_t str_size = str.size(), match_size = strlen(match);
108     if (match_size > str_size)
109         return false;
110 
111     std::string::const_iterator s = str.end() - match_size;
112     while (*match != 0) {
113         if (to_lower(*s) != to_lower(*match)) return false;
114         ++s, ++match;
115     }
116     return true;
117 }
118 
ends_with_icase(const std::string & str,const std::string & match)119 bool ends_with_icase(const std::string& str, const std::string& match) {
120     if (match.size() > str.size())
121         return false;
122 
123     return std::equal(match.begin(), match.end(), str.end() - match.size(),
124                       [](const char& c1, const char& c2) {
125                           return to_lower(c1) == to_lower(c2);
126                       });
127 }
128 
129 /******************************************************************************/
130 
131 } // namespace tlx
132 
133 /******************************************************************************/
134