From caae1e38d0d239f4f7088a64526fe1d2f6587999 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Thu, 26 Sep 2013 23:55:29 -0700 Subject: Split string header into pieces --- src/strings/base.tcc | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 src/strings/base.tcc (limited to 'src/strings/base.tcc') diff --git a/src/strings/base.tcc b/src/strings/base.tcc new file mode 100644 index 0000000..cde277f --- /dev/null +++ b/src/strings/base.tcc @@ -0,0 +1,442 @@ +// strings/base.tcc - Inline functions for strings/base.hpp +// +// Copyright © 2013 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// 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 . + +#include + +#include "pair.hpp" + +namespace strings +{ + namespace detail + { + constexpr + bool is_print(char c) + { + return ' ' <= c && c <= '~'; + } + constexpr + bool is_graph(char c) + { + return is_print(c) && c != ' '; + } + constexpr + bool is_lower(char c) + { + return 'a' <= c && c <= 'z'; + } + constexpr + bool is_upper(char c) + { + return 'A' <= c && c <= 'Z'; + } + constexpr + bool is_alpha(char c) + { + return is_lower(c) || is_upper(c); + } + constexpr + bool is_digit2(char c) + { + return '0' <= c && c <= '1'; + } + constexpr + bool is_digit8(char c) + { + return '0' <= c && c <= '7'; + } + constexpr + bool is_digit10(char c) + { + return '0' <= c && c <= '9'; + } + constexpr + bool is_digit16(char c) + { + return ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'); + } + constexpr + bool is_alnum(char c) + { + return is_alpha(c) || is_digit10(c); + } + + constexpr + char to_lower(char c) + { + return is_upper(c) ? c | ' ' : c; + } + constexpr + char to_upper(char c) + { + return is_lower(c) ? c & ~' ' : c; + } + } // namespace detail + + template + const T& _crtp_string::_ref() const + { + return static_cast(*this); + } + template + typename _crtp_string::iterator _crtp_string::begin() const + { + return _ref().begin(); + } + template + typename _crtp_string::iterator _crtp_string::end() const + { + return _ref().end(); + } + template + const FString *_crtp_string::base() const + { + return _ref().base(); + } + template + size_t _crtp_string::size() const + { + return end() - begin(); + } + template + typename _crtp_string::reverse_iterator _crtp_string::rbegin() const + { + return reverse_iterator(end()); + } + template + typename _crtp_string::reverse_iterator _crtp_string::rend() const + { + return reverse_iterator(begin()); + } + template + _crtp_string::operator bool() const + { + return size(); + } + template + bool _crtp_string::operator !() const + { + return !size(); + } + template + _crtp_string::operator P() const + { + return {&*begin(), &*end()}; + } + + template + __attribute__((deprecated)) + char _crtp_string::operator[](size_t i) const + { + return begin()[i]; + } + template + char _crtp_string::front() const + { + return *begin(); + } + template + char _crtp_string::back() const + { + return end()[-1]; + } + template + const char *_crtp_string::data() + { + return &*begin(); + } + + template + typename P::TailSlice _crtp_string::xslice_t(size_t o) const + { + return typename P::TailSlice(&begin()[o], &*end(), base()); + } + template + typename P::FullSlice _crtp_string::xslice_h(size_t o) const + { + return typename P::FullSlice(&*begin(), &begin()[o], base()); + } + template + typename P::TailSlice _crtp_string::xrslice_t(size_t no) const + { + return typename P::TailSlice(&end()[-no], &*end(), base()); + } + template + typename P::FullSlice _crtp_string::xrslice_h(size_t no) const + { + return typename P::FullSlice(&*begin(), &end()[-no], base()); + } + template + typename P::TailSlice _crtp_string::xislice_t(iterator it) const + { + return typename P::TailSlice(&*it, &*end(), base()); + } + template + typename P::FullSlice _crtp_string::xislice_h(iterator it) const + { + return typename P::FullSlice(&*begin(), &*it, base()); + } + template + typename P::FullSlice _crtp_string::xlslice(size_t o, size_t l) const + { + return typename P::FullSlice(&begin()[o], &begin()[o + l], base()); + } + template + typename P::FullSlice _crtp_string::xpslice(size_t b, size_t e) const + { + return typename P::FullSlice(&begin()[b], &begin()[e], base()); + } + template + typename P::FullSlice _crtp_string::xislice(iterator b, iterator e) const + { + return typename P::FullSlice(&*b, &*e, base()); + } + template + typename P::TailSlice _crtp_string::lstrip() const + { + typename P::TailSlice z = _ref(); + while (z.startswith(' ')) + z = z.xslice_t(1); + return z; + } + template + typename P::FullSlice _crtp_string::rstrip() const + { + typename P::FullSlice x = _ref(); + while (x.endswith(' ')) + x = x.xrslice_h(1); + return x; + } + template + typename P::FullSlice _crtp_string::strip() const + { + return lstrip().rstrip(); + } + + template + bool _crtp_string::startswith(XPair x) const + { + return size() >= x.size() && pair_compare(xslice_h(x.size()), x) == 0; + } + template + bool _crtp_string::endswith(XPair x) const + { + return size() > x.size() && pair_compare(xrslice_t(x.size()), x) == 0; + } + template + bool _crtp_string::startswith(char c) const + { + return size() && front() == c; + } + template + bool _crtp_string::endswith(char c) const + { + return size() && back() == c; + } + template + bool _crtp_string::contains(char c) const + { + return std::find(begin(), end(), c) != end(); + } + template + bool _crtp_string::contains_seq(XPair s) const + { + return std::search(begin(), end(), s.begin(), s.end()) != end(); + } + template + bool _crtp_string::contains_any(XPair s) const + { + return std::find_if(s.begin(), s.end(), [this](char c) { return this->contains(c); }) != end(); + } + + template + bool _crtp_string::has_print() const + { + return std::find_if(begin(), end(), detail::is_print) != end(); } + template + bool _crtp_string::is_print() const + { + return std::find_if_not(begin(), end(), detail::is_print) == end(); } + template + O _crtp_string::to_print() const + { + if (is_print()) return _ref(); + char buf[size()]; + char *const b = buf; + char *const e = std::transform(begin(), end(), b, [](char c) { return detail::is_print(c) ? c : '_'; }); + return XPair(b, e); + } + + template + bool _crtp_string::has_graph() const + { + return std::find_if(begin(), end(), detail::is_graph) != end(); + } + template + bool _crtp_string::is_graph() const + { + return std::find_if_not(begin(), end(), detail::is_graph) == end(); + } + + template + bool _crtp_string::has_lower() const + { + return std::find_if(begin(), end(), detail::is_lower) != end(); + } + template + bool _crtp_string::is_lower() const + { + return std::find_if_not(begin(), end(), detail::is_lower) == end(); + } + template + O _crtp_string::to_lower() const + { + if (!has_upper()) return _ref(); + char buf[size()]; + char *const b = buf; + char *const e = std::transform(begin(), end(), b, detail::to_lower); + return XPair(b, e); + } + + template + bool _crtp_string::has_upper() const + { + return std::find_if(begin(), end(), detail::is_upper) != end(); + } + template + bool _crtp_string::is_upper() const + { + return std::find_if_not(begin(), end(), detail::is_upper) == end(); + } + template + O _crtp_string::to_upper() const + { + if (!has_lower()) return _ref(); + char buf[size()]; + char *const b = buf; + char *const e = std::transform(begin(), end(), b, detail::to_upper); + return XPair(b, e); + } + + template + bool _crtp_string::has_alpha() const + { + return std::find_if(begin(), end(), detail::is_alpha) != end(); + } + template + bool _crtp_string::is_alpha() const + { + return std::find_if_not(begin(), end(), detail::is_alpha) == end(); + } + + template + bool _crtp_string::has_digit2() const + { + return std::find_if(begin(), end(), detail::is_digit2) != end(); + } + template + bool _crtp_string::is_digit2() const + { + return std::find_if_not(begin(), end(), detail::is_digit2) == end(); + } + template + bool _crtp_string::has_digit8() const + { + return std::find_if(begin(), end(), detail::is_digit8) != end(); + } + template + bool _crtp_string::is_digit8() const + { + return std::find_if_not(begin(), end(), detail::is_digit8) == end(); + } + template + bool _crtp_string::has_digit10() const + { + return std::find_if(begin(), end(), detail::is_digit10) != end(); + } + template + bool _crtp_string::is_digit10() const + { + return std::find_if_not(begin(), end(), detail::is_digit10) == end(); + } + template + bool _crtp_string::has_digit16() const + { + return std::find_if(begin(), end(), detail::is_digit16) != end(); + } + template + bool _crtp_string::is_digit16() const + { + return std::find_if_not(begin(), end(), detail::is_digit16) == end(); + } + + template + bool _crtp_string::has_alnum() const + { + return std::find_if(begin(), end(), detail::is_alnum) != end(); + } + template + bool _crtp_string::is_alnum() const + { + return std::find_if_not(begin(), end(), detail::is_alnum) == end(); + } + + // not really intended for public use + inline + int pair_compare(XPair l, XPair r) + { + bool less = std::lexicographical_compare( + l.begin(), l.end(), + r.begin(), r.end()); + bool greater = std::lexicographical_compare( + r.begin(), r.end(), + l.begin(), l.end()); + return greater - less; + } + + template + auto operator == (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) == 0; + } + template + auto operator != (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) != 0; + } + template + auto operator < (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) < 0; + } + template + auto operator <= (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) <= 0; + } + template + auto operator > (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) > 0; + } + template + auto operator >= (const L& l, const R& r) -> decltype((pair_compare(l, r), true)) + { + return pair_compare(l, r) >= 0; + } +} // namespace strings -- cgit v1.2.3-70-g09d2