diff --git a/SimoxUtility/CMakeLists.txt b/SimoxUtility/CMakeLists.txt index 4d336ca1ca9b22650138c1a3ec2a4914ae84cd15..8e5c50a6de8de92b71c932d438c71de064fda6c6 100644 --- a/SimoxUtility/CMakeLists.txt +++ b/SimoxUtility/CMakeLists.txt @@ -101,6 +101,7 @@ SET(INCLUDES algorithm/advanced.h algorithm/apply.hpp + algorithm/contains.h algorithm/for_each_if.h algorithm/fuzzy_find.h algorithm/get_map_keys_values.h diff --git a/SimoxUtility/algorithm.h b/SimoxUtility/algorithm.h index a4752d98709411b0351ec0376e155c5d794d88a6..bc7252a2cee84dc106b548b5a3e3025bdae0c14e 100644 --- a/SimoxUtility/algorithm.h +++ b/SimoxUtility/algorithm.h @@ -3,6 +3,7 @@ // This file is generated! #include "algorithm/advanced.h" +#include "algorithm/contains.h" #include "algorithm/for_each_if.h" #include "algorithm/fuzzy_find.h" #include "algorithm/get_map_keys_values.h" diff --git a/SimoxUtility/algorithm/contains.h b/SimoxUtility/algorithm/contains.h new file mode 100644 index 0000000000000000000000000000000000000000..45516257dff2a166ed516779558e4498ef93954c --- /dev/null +++ b/SimoxUtility/algorithm/contains.h @@ -0,0 +1,79 @@ +#pragma once + +#include <algorithm> +#include <functional> +#include <string> +#include <map> + + +namespace simox::alg +{ + + // For overloads of `simox::alg::contains` taking `std::string`: + // #include <SimoxUtility/algorithm/string/string_tools.h> + + // GENERAL CONTAINERS + + /** + * Return true if `value` is an element of `container`, false otherwise. + */ + template <class ContainerT, class ValueT> + bool contains(const ContainerT& container, const ValueT& value) + { + return std::find_if(container.begin(), container.end(), [&value](const auto& v) + { + return v == value; + }) != container.end(); + } + + /** + * Return true if `value` is an element of `container` (as indicated by `predicate`), + * false otherwise. + */ + template <class ContainerT, class ValueT, class PredicateT> + bool contains(const ContainerT& container, const ValueT& value, const PredicateT& predicate) + { + return std::find_if(container.begin(), container.end(), [&value, &predicate](const auto& v) + { + return predicate(v, value); + }) != container.end(); + } + + + // MAPS + + /** + * Return true if `key` is a key in `map`, false otherwise. + */ + template <class K, class V, template<class...> class MapT = std::map, class...Ts> + bool contains_key(const MapT<K, V, Ts...>& map, const K& key) + { + return map.count(key) > 0; + } + + /** + * Return true if `value` is a value in `map`, false otherwise. + */ + template <class K, class V, template<class...> class MapT = std::map, class...Ts> + bool contains_value(const MapT<K, V, Ts...>& map, const V& value) + { + return std::find_if(map.begin(), map.end(), [&value](const std::pair<K, V>& item) + { + return item.second == value; + }) != map.end(); + } + + + // Overloads for string literals (which otherwise don't match the previous definition). + template <class V, template<class...> class MapT = std::map, class...Ts> + bool contains_key(const MapT<std::string, V, Ts...>& map, const std::string& key) + { + return map.count(key) > 0; + } + template <class K, template<class...> class MapT = std::map, class...Ts> + bool contains_value(const MapT<K, std::string, Ts...>& map, const std::string& value) + { + return contains_value<K, std::string>(map, value); + } + +}