// // libsemigroups - C++ library for semigroups and monoids // Copyright (C) 2019 James D. Mitchell // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. //
// This file contains some string related functionality.
// A << function for vectors template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const& vec) { if (vec.empty()) {
os << "{}"; return os;
}
os << "{{"; // {{ is an escaped single { for fmt for (auto it = vec.cbegin(); it < vec.cend() - 1; ++it) {
os << detail::to_string(*it) << ", ";
}
os << detail::to_string(*(vec.cend() - 1)) << "}}"; return os;
}
// A << function for arrays template <typename T, size_t N>
std::ostream& operator<<(std::ostream& os, std::array<T, N> const& rry) {
os << "{{"; for (auto it = rry.cbegin(); it < rry.cend() - 1; ++it) {
os << detail::to_string(*it) << ", ";
}
os << detail::to_string(*(rry.cend() - 1)) << "}}"; return os;
}
// A << function for pairs template <typename T, typename S>
std::ostream& operator<<(std::ostream& os, std::pair<T, S> const& p) {
os << "{{" << detail::to_string(p.first) << ", "
<< detail::to_string(p.second) << "}}"; return os;
}
namespace detail { // TODO(later) preprocess the next 3 functions out if using clang or gcc > 5 // A << function for vectors - to keep gcc 5 happy template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const& vec) { return ::libsemigroups::operator<<(os, vec);
}
// A << function for arrays - to keep gcc 5 happy template <typename T, size_t N>
std::ostream& operator<<(std::ostream& os, std::array<T, N> const& rry) { return ::libsemigroups::operator<<(os, rry);
}
// A << function for pairs - to keep gcc 5 happy template <typename T, typename S>
std::ostream& operator<<(std::ostream& os, std::pair<T, S> const& p) { return ::libsemigroups::operator<<(os, p);
}
// Returns a string representing an object of type \c T. // // It appears that GCC 4.9.1 (at least) does not have std::to_string // implemented, so we implement our own. This requires the operator \c << // to be implemented for an \c ostringstream& and const T& element. template <typename T>
std::string to_string(T const& n) {
std::ostringstream stm;
stm << n; return stm.str();
}
// Returns true if [first_prefix, last_prefix) is a prefix of [first_word, // last_word). // Not noexcept, because std::equal isn't template <typename S, typename T> bool is_prefix(S first_word, S last_word, T first_prefix, T last_prefix) {
LIBSEMIGROUPS_ASSERT(first_word <= last_word); // Check if [first_prefix, last_prefix) equals [first_word, first_word + // (last_prefix - first_prefix)) if (!(first_prefix <= last_prefix)) { returnfalse;
} elseif (!(last_prefix - first_prefix <= last_word - first_word)) { returnfalse;
} elseif (!std::equal(first_prefix, last_prefix, first_word)) { returnfalse;
} returntrue;
}
// Check if v is a prefix of u staticinlinebool is_prefix(std::string const& u, std::string const& v) { return is_prefix(u.cbegin(), u.cend(), v.cbegin(), v.cend());
}
template <typename S, typename T>
std::pair<S, T> maximum_common_prefix(S first_word1,
S last_word1,
T first_word2,
T last_word2) { // TODO there must be a better way of doing the static_casts in the next // line while (first_word1 < last_word1 && first_word2 < last_word2
&& static_cast<uint64_t>(*first_word1)
== static_cast<uint64_t>(*first_word2)) {
++first_word1;
++first_word2;
} return std::make_pair(first_word1, first_word2);
}
template <typename T>
std::pair<T, T> maximum_common_suffix(T first_word1,
T last_word1,
T first_word2,
T last_word2) { auto p = maximum_common_prefix(std::make_reverse_iterator(last_word1),
std::make_reverse_iterator(first_word1),
std::make_reverse_iterator(last_word2),
std::make_reverse_iterator(first_word2)); return std::make_pair(p.first.base(), p.second.base());
}
template <typename W> staticinlineauto maximum_common_suffix(W const& u, W const& v) { return W(maximum_common_suffix(u.cbegin(), u.cend(), v.cbegin(), v.cend())
.first,
u.cend());
}
staticinlineauto maximum_common_suffix(charconst* u, charconst* v) { return std::string(
maximum_common_suffix(u, u + std::strlen(u), v, v + std::strlen(v))
.first,
u + std::strlen(u));
}
template <typename W> staticinlineauto maximum_common_prefix(W const& u, W const& v) { return maximum_common_prefix(u.cbegin(), u.cend(), v.cbegin(), v.cend());
}
// Returns true if [first_suffix, last_suffix) is a suffix of [first_word, // last_word). template <typename S, typename T> bool is_suffix(S first_word, S last_word, T first_suffix, T last_suffix) { return is_prefix(std::make_reverse_iterator(last_word),
std::make_reverse_iterator(first_word),
std::make_reverse_iterator(last_suffix),
std::make_reverse_iterator(first_suffix));
}
// Check if v is a suffix of u staticinlinebool is_suffix(std::string const& u, std::string const& v) { return is_suffix(u.cbegin(), u.cend(), v.cbegin(), v.cend());
}
// Random string with length <length> over <alphabet>.
std::string random_string(std::string const& alphabet, size_t length);
// Random string with random length in the range [min, max) over <alphabet>
std::string random_string(std::string const& alphabet,
size_t min,
size_t max);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.