// Copyright 2022 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source // License, and you may not use this file except in compliance with the Business Source License. // // As of the Change Date specified in that file, in accordance with // the Business Source License, use of this software will be governed // by the Apache License, Version 2.0, included in the file // licenses/APL.txt. #pragma once #include #include #include #include #include #include #include "utils/exceptions.hpp" namespace memgraph::utils { /** * Outputs a collection of items to the given stream, separating them with the * given delimiter. * * @param stream Destination stream. * @param first Starting iterator of collection which items are going to be * printed. * @param last Ending iterator of the collection. * @param delim Delimiter that is put between items. * @param streamer Function which accepts a TStream and an item and streams the * item to the stream. */ template inline void PrintIterable(TStream *stream, TIterator first, TIterator last, const std::string &delim = ", ", TStreamer streamer = {}) { if (first != last) { streamer(*stream, *first); ++first; } for (; first != last; ++first) { *stream << delim; streamer(*stream, *first); } } /** * Outputs a collection of items to the given stream, separating them with the * given delimiter. * * @param stream Destination stream. * @param iterable An iterable collection of items. * @param delim Delimiter that is put between items. * @param streamer Function which accepts a TStream and an item and * streams the item to the stream. */ template inline void PrintIterable(TStream &stream, const TIterable &iterable, const std::string &delim = ", ", TStreamer streamer = {}) { PrintIterable(&stream, iterable.begin(), iterable.end(), delim, streamer); } /** * Outputs a collection of items to the given stream, separating them with the * given delimiter. * * @param stream Destination stream. * @param iterable An iterable collection of items. * @param delim Delimiter that is put between items. */ template inline void PrintIterable(TStream &stream, const TIterable &iterable, const std::string &delim = ", ") { PrintIterable(stream, iterable, delim, [](auto &stream, const auto &item) { stream << item; }); } /** * Finds a mapping if it exists for given key or returns the provided value. * * @param map A map-like container which has the `find` method. * @param key Key to look for in the map. * @param or_value Value to use if the key is not in the map. * @return Pair of value and a boolean indicating whether the key was in the * map. */ template inline std::pair FindOr(const TMap &map, const TKey &key, TVal &&or_value) { auto it = map.find(key); if (it != map.end()) return {it->second, true}; return {std::forward(or_value), false}; } /** * Returns the *copy* of the first element from an iterable. * * @param iterable An iterable collection of values. * @return The first element of the `iterable`. * @exception BasicException is thrown if the `iterable` is empty. */ template inline auto First(TIterable &&iterable) { if (iterable.begin() != iterable.end()) return *iterable.begin(); throw utils::BasicException("Empty iterable"); } /** * Returns the *copy* of the first element from an iterable. * * @param iterable An iterable collection of values. * @param empty_value Value to return if the `iterable` is empty. * @return The first element of the `iterable` or the `empty_value`. */ template inline TVal First(TIterable &&iterable, TVal &&empty_value) { if (iterable.begin() != iterable.end()) return *iterable.begin(); return empty_value; } template bool Contains(const std::unordered_set &iterable, const TElement &element) { return iterable.find(element) != iterable.end(); } template bool Contains(const std::unordered_map &iterable, const TKey &key) { return iterable.find(key) != iterable.end(); } /** * Returns `true` if the given iterable contains the given element. * * @param iterable An iterable collection of values. * @param element The sought element. * @return `true` if element is contained in iterable. * @tparam TIiterable type of iterable. * @tparam TElement type of element. */ template inline bool Contains(const TIterable &iterable, const TElement &element) { return std::find(iterable.begin(), iterable.end(), element) != iterable.end(); } /** * Return a reversed copy of the given collection. * The copy is allocated using the default allocator. */ template TCollection Reversed(const TCollection &collection) { return TCollection(std::rbegin(collection), std::rend(collection)); } /** * Return a reversed copy of the given collection. * The copy is allocated with the given `alloc`. */ template TCollection Reversed(const TCollection &collection, const TAllocator &alloc) { return TCollection(std::rbegin(collection), std::rend(collection), alloc); } /** * Converts a (beginning, end) pair of iterators into an iterable that can be * passed on to itertools. */ template class Iterable { public: Iterable(TIterator &&begin, TIterator &&end) : begin_(std::forward(begin)), end_(std::forward(end)) {} auto begin() { return begin_; }; auto end() { return end_; }; private: TIterator begin_; TIterator end_; }; } // namespace memgraph::utils