// Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. // https://github.com/Dobiasd/FunctionalPlus // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #pragma once #include #include #include #include namespace fplus { // API search type: set_includes : (Set a, Set a) -> Bool // fwd bind count: 1 // Checks if every element of the second set is also present in the first set. // Also known as is_subset_of. template bool set_includes(const SetType& set1, const SetType& set2) { return std::includes(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2)); } // API search type: unordered_set_includes : (Unordered_Set a, Unordered_Set a) -> Bool // fwd bind count: 1 // Checks if every element of the second unordered_set // is also present in the first unordered_set. // Also known as is_subset_of. template bool unordered_set_includes(const UnorderSetType& set1, const UnorderSetType& set2) { auto first_not_included = std::find_if(set2.begin(), set2.end(), [&](const typename UnorderSetType::value_type& x) -> bool { return set1.find(x) == set1.end();}); return first_not_included == set2.end(); } // API search type: set_merge : (Set a, Set a) -> Set a // fwd bind count: 1 // Returns the union of two given sets. template SetType set_merge(const SetType& set1, const SetType& set2) { SetType result; auto itOut = internal::get_back_inserter(result); std::merge(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2), itOut); return result; } // API search type: unordered_set_merge : (Unordered_Set a, Unordered_Set a) -> Unordered_Set a // fwd bind count: 1 // Returns the union of two given sets. template UnorderSetType unordered_set_merge(const UnorderSetType& set1, const UnorderSetType& set2) { UnorderSetType result; auto itOut = internal::get_back_inserter(result); std::copy(std::begin(set1), std::end(set1), itOut); std::copy(std::begin(set2), std::end(set2), itOut); return result; } // API search type: set_intersection : (Set a, Set a) -> Set a // fwd bind count: 1 // Returns the intersection of both sets. template SetType set_intersection(const SetType& set1, const SetType& set2) { SetType result; auto itOut = internal::get_back_inserter(result); std::set_intersection(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2), itOut); return result; } // API search type: unordered_set_intersection : (Unordered_Set a, Unordered_Set a) -> Unordered_Set a // fwd bind count: 1 // Returns the intersection of both unordered_sets. template UnorderSetType unordered_set_intersection( const UnorderSetType& set1, const UnorderSetType& set2) { UnorderSetType result; auto itOut = internal::get_back_inserter(result); std::copy_if(std::begin(set2), std::end(set2), itOut, [&](const typename UnorderSetType::value_type &x) -> bool {return set1.find(x) != set1.end();}); return result; } // API search type: set_is_disjoint : (Set a, Set a) -> Bool // fwd bind count: 1 // Checks if two sets are disjoint. template bool set_is_disjoint(const SetType& set1, const SetType& set2) { return set_intersection(set1, set2).empty(); } // API search type: unordered_set_is_disjoint : (Unordered_Set a, Unordered_Set a) -> Bool // fwd bind count: 1 // Checks if two unordered_sets are disjoint. template bool unordered_set_is_disjoint( const UnorderSetType& set1, const UnorderSetType& set2) { return unordered_set_intersection(set1, set2).empty(); } // API search type: set_difference : (Set a, Set a) -> Set a // fwd bind count: 1 // Returns the elements in set1 that are not present in set2. template SetType set_difference(const SetType& set1, const SetType& set2) { SetType result; auto itOut = internal::get_back_inserter(result); std::set_difference(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2), itOut); return result; } // API search type: unordered_set_difference : (Unordered_Set a, Unordered_Set a) -> Unordered_Set a // fwd bind count: 1 // Returns the elements in unordered_set1 // that are not present in unordered_set2. template UnorderSetType unordered_set_difference(const UnorderSetType& set1, const UnorderSetType& set2) { UnorderSetType result; auto itOut = internal::get_back_inserter(result); std::copy_if(std::begin(set1), std::end(set1), itOut, [&](const typename UnorderSetType::value_type &x) -> bool {return set2.find(x) == set2.end();}); return result; } // API search type: set_symmetric_difference : (Set a, Set a) -> Set a // fwd bind count: 1 // Returns the symmetric difference of both sets. template SetType set_symmetric_difference(const SetType& set1, const SetType& set2) { SetType result; auto itOut = internal::get_back_inserter(result); std::set_symmetric_difference(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2), itOut); return result; } // API search type: unordered_set_symmetric_difference : (Unordered_Set a, Unordered_Set a) -> Unordered_Set a // fwd bind count: 1 // Returns the symmetric difference of both unordered_sets. template UnorderSetType unordered_set_symmetric_difference( const UnorderSetType& set1, const UnorderSetType& set2) { UnorderSetType result; auto itOut = internal::get_back_inserter(result); std::copy_if(std::begin(set1), std::end(set1), itOut, [&](const typename UnorderSetType::value_type &x) -> bool {return set2.find(x) == set2.end();}); std::copy_if(std::begin(set2), std::end(set2), itOut, [&](const typename UnorderSetType::value_type &x) -> bool {return set1.find(x) == set1.end();}); return result; } // API search type: sets_intersection : [Set a] -> Set a // fwd bind count: 0 // Returns the intersection of the given sets. // Also known as intersect_many. // For performance try to sort the inputs sets prior, ascendending by size. template SetType sets_intersection(const ContainerIn& sets) { return fold_left_1(set_intersection, sets); } // API search type: unordered_sets_intersection : [Unordered_Set a] -> Unordered_Set a // fwd bind count: 0 // Returns the intersection of the given unordered_sets. // Also known as intersect_many. template UnordSetType unordered_sets_intersection(const ContainerIn& sets) { return fold_left_1(unordered_set_intersection, sets); } } // namespace fplus