/* * Copyright (c) 2014, killerbee13 * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef SIMPLE_ALGORITHMS_H_INCLUDED #define SIMPLE_ALGORITHMS_H_INCLUDED // Header containing frequently reused code that is not as easily done without // helper functions #include #include #include #include #include #include #include #include #include #include #include #include #include #if __has_cpp_attribute(fallthrough) # define fallthrough fallthrough #elif __has_cpp_attribute(clang::fallthrough) # define fallthrough clang::fallthrough #elif __has_cpp_attribute(gnu::fallthrough) # define fallthrough gnu::fallthrough #else # define fallthrough fallthrough #endif #if __has_cpp_attribute(maybe_unused) # define maybe_unused maybe_unused #elif __has_cpp_attribute(gnu::unused) # define maybe_unused gnu::unused #else // Just let the compiler show the warning # define maybe_unused maybe_unused #endif #if not FRC_NO_CONVERT # include # include // This is the only one that should throw an exception template inline T fromStr(const std::string& val) { std::stringstream ss(val); T ret; if (not (ss >> ret).fail()) return ret; else throw std::runtime_error("\"" + val + "\" is not a " + typeid(T).name()); } template <> inline std::string fromStr(const std::string& val) { return val; } template inline T fromStr(const std::string& val, const char* type) { std::stringstream ss(val); T ret; if (not (ss >> ret).fail()) return ret; else throw std::runtime_error("\"" + val + "\" is not a " + type); } template <> inline std::string fromStr(const std::string& val, [[maybe_unused]] const char* type) { return val; } # define pFromStr(type, val) fromStr((val), # type) template inline std::string toStr(T val) { std::stringstream ss; ss << val; return ss.str(); } #endif #if not FRC_NO_ICU # include // For elegance template inline string toUTF8(const icu::UnicodeString& s) { string res; return s.toUTF8String(res); } // For consistency template inline icu::UnicodeString fromUTF8(string s) { return icu::UnicodeString::fromUTF8(s); } // For elegance template inline string toUTF32(const icu::UnicodeString& s) { string res(s.countChar32(), '\0'); UErrorCode ec{U_ZERO_ERROR}; s.toUTF32(reinterpret_cast(&res[0]), res.size(), ec); if (U_FAILURE(ec)) { throw ec; } return res; } // For consistency template inline icu::UnicodeString fromUTF32(string s) { return icu::UnicodeString::fromUTF32(s.data(), s.length()); } inline std::ostream& operator<<(std::ostream& os, const icu::UnicodeString& str) { return os << toUTF8(str); } // ICU basically provides a + so I might as well translate it inline std::string operator+(std::string lhs, const icu::UnicodeString& str) { return str.toUTF8String(lhs); } # if not FRC_NO_CONVERT // For debugging std::string d_toUTF8(const icu::UnicodeString& s); icu::UnicodeString d_fromUTF8(std::string s); template inline T fromStr(const icu::UnicodeString& val, const char* type) { return fromStr(toUTF8(val), type); } template inline T fromStr(const icu::UnicodeString& val) { return fromStr(toUTF8(val)); } # endif #endif #include template inline string join(const vector& in, const string& joiner = {}) { if (in.size() == 0) { return {}; } else if (in.size() == 1) { return *in.begin(); } else { return std::accumulate( std::next(std::begin(in)), std::end(in), *in.begin(), [&joiner](const string& a, const string& b) -> string { return a + joiner + b; }); } } template inline string reverseStr(string val) { std::reverse(val.begin(), val.end()); return val; } template inline string toLower(string str) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); return str; } template inline string toUpper(string str) { std::transform(str.begin(), str.end(), str.begin(), ::toupper); return str; } #include #include #include template inline std::vector listToVec(std::string list) { std::vector ret; std::stringstream ss(list); std::string tmp; while (not (ss >> tmp).fail()) { ret.push_back(fromStr(tmp)); } /* while(list.find_first_of(" ,") != std::string::npos) { std::string entry = list.substr(0, list.find_first_of(" ,")); ret.push_back(fromStr(entry)); list = list.substr(entry.size()); if (list.find_first_of(" ,") == std::string::npos) { entry = list.substr(0, list.find_first_of(" ,")); ret.push_back(fromStr(entry)); list = list.substr(entry.size()); } }*/ return ret; } template inline string repeat(string val, int count) { string tmp; for (int i = 0; i < count; ++i) { tmp += val; } return tmp; } inline std::string repeat(char val, int count) { return std::string(count, val); } #if not FRC_NO_BUILD # include # include template inline Container build(InputIt first, InputIt last, UnaryFunction f) { Container out; std::transform(first, last, std::back_inserter(out), f); return out; } template inline Container build(InputIt first, InputIt last, InputIt2 first2, BinaryFunction f) { Container out; std::transform(first, last, first2, std::back_inserter(out), f); return out; } template inline Container build(ExecutionPolicy&& policy, InputIt first, InputIt last, UnaryFunction f) { Container out; std::transform(policy, first, last, std::back_inserter(out), f); return out; } template inline Container build(ExecutionPolicy&& policy, InputIt first, InputIt last, InputIt2 first2, BinaryFunction f) { Container out; std::transform(policy, first, last, first2, std::back_inserter(out), f); return out; } #endif template constexpr inline int digitsOf(Number val) { return std::ceil(std::log10(val)); } template constexpr inline int digitsOf(Number val, int base) { return std::ceil(std::log(val) / std::log(base)); } template inline int digitsList(ForwardIterator first, ForwardIterator last) { return digitsOf(*std::max_element(first, last)); } template inline int digitsList(ForwardIterator first, ForwardIterator last, int base) { return digitsOf(*std::max_element(first, last), base); } #include // Not working template inline ostream_type& padList(ostream_type& os, ForwardIterator first, ForwardIterator last, char fill = ' ', int base = 10) { // os< inline std::string get_file_contents(string filename) { std::ifstream in{}; in.exceptions(std::ios::badbit); in.open(filename, std::ios::in | std::ios::binary); std::string contents; std::array buf; while (in) { in.read(buf.begin(), buf.size()); contents.append(buf.begin(), in.gcount()); } return contents; } template inline constexpr T quantizeRange(F min, F delta, F val) { return static_cast((val - min) * std::numeric_limits::max() * delta); } // Memnonic aids template using Ptr = T*; template using PtrToConst = T const*; template using ConstPtr = T* const; template using ConstPtrToConst = T const* const; #endif // SIMPLE_ALGORITHMS_H_INCLUDED