// itlib-qalgorithm v1.03 // // Wrappers of algorithms for entire containers // // SPDX-License-Identifier: MIT // MIT License: // Copyright(c) 2020-2023 Borislav Stanimirov // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files(the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and / or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions : // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // // VERSION HISTORY // // 1.03 (2023-02-07) qall_of, qany_of, qnone_of, identity // 1.02 (2022-11-29) span-compatible pfind and pfind_if // 1.01 (2020-12-29) Added erase functions // 1.00 (2020-12-28) First pulic release // // // DOCUMENTATION // // Simply include this file wherever you need. // It defines the following algorithms: // // * qfind - wraps std::find // * qfind_if - wraps std::find_if // * pfind - wraps std::find, returns a raw pointer to the element or nullptr if the element wasn't found // * pfind_if - wraps std::find_if, returns a raw pointer to the element or nullptr if the element wasn't found // * bool erase_first(container, value) - erase the first element equal to value. returns true if something was erased // * bool erase_first_if(container, pred) - erase the first elemenf which matches pred. returns true if something was erased // * size_t erase_all(container, value) - erases all elements equal to value, returns number of elements erased // * size_t erase_all_if(container, value) - erases all elements which match pred, returns number of elements erased // * bool qall_of(container, pred = identity) - checks if all elements evaluate to true with predicate // * bool qany_of(container, pred = identity) - checks if any elements evaluate to true with predicate // * bool qnone_of(container, pred = identity) - checks if no elements evaluate to true with predicate // // ... and the following types: // * identity - an identity unary predicate similar to C++20's std::identity // // TESTS // // You can find unit tests for qalgorithm in its official repo: // https://github.com/iboB/itlib/blob/master/test/ // #pragma once #include #include #include namespace itlib { namespace impl { // get the appropriate return type: iterator for non-const containers and const_iterator for const containers template struct iterator_t { using type = typename std::conditional::value, typename Container::const_iterator, typename Container::iterator>::type; }; template struct pointer_t { using type = typename std::conditional::value, typename Container::const_pointer, typename Container::pointer>::type; }; } template typename impl::iterator_t::type qfind(Container& c, const Value& val) { return std::find(c.begin(), c.end(), val); } template typename impl::pointer_t::type pfind(Container& c, const Value& val) { auto f = std::find(c.begin(), c.end(), val); if (f == c.end()) return nullptr; return &(*f); } template typename impl::iterator_t::type qfind_if(Container& c, Pred&& pred) { return std::find_if(c.begin(), c.end(), std::forward(pred)); } template typename impl::pointer_t::type pfind_if(Container& c, Pred&& pred) { auto f = std::find_if(c.begin(), c.end(), std::forward(pred)); if (f == c.end()) return nullptr; return &(*f); } template bool erase_first(Container& c, const Value& val) { auto f = qfind(c, val); if (f == c.end()) return false; c.erase(f); return true; } template bool erase_first_if(Container& c, Pred&& pred) { auto f = qfind_if(c, std::forward(pred)); if (f == c.end()) return false; c.erase(f); return true; } template typename Container::size_type erase_all(Container& c, const Value& val) { auto newend = std::remove(c.begin(), c.end(), val); auto ret = c.end() - newend; c.erase(newend, c.end()); return ret; } template typename Container::size_type erase_all_if(Container& c, Pred&& pred) { auto newend = std::remove_if(c.begin(), c.end(), std::forward(pred)); auto ret = c.end() - newend; c.erase(newend, c.end()); return ret; } struct identity { template const T& operator()(const T& t) { return t; } }; template bool qall_of(const Container& c, Pred&& pred) { return std::all_of(c.begin(), c.end(), std::forward(pred)); } template bool qall_of(const Container& c) { return qall_of(c, identity{}); } template bool qany_of(const Container& c, Pred&& pred) { return std::any_of(c.begin(), c.end(), std::forward(pred)); } template bool qany_of(const Container& c) { return qany_of(c, identity{}); } template bool qnone_of(const Container& c, Pred&& pred) { return std::none_of(c.begin(), c.end(), std::forward(pred)); } template bool qnone_of(const Container& c) { return qnone_of(c, identity{}); } }