Skip to content
Snippets Groups Projects
Commit d9ca2c5b authored by Jan Trávníček's avatar Jan Trávníček
Browse files

graph_algo: introduce ext::unordered_set

parent 501b8475
No related branches found
No related tags found
1 merge request!206Merge jt
#include <ext/unordered_set>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
   
#pragma once #pragma once
   
#include <unordered_set> #include <alib/unordered_set>
   
#include <graph/GraphClasses.hpp> #include <graph/GraphClasses.hpp>
#include <node/NodeClasses.hpp> #include <node/NodeClasses.hpp>
...@@ -23,7 +23,7 @@ namespace graph { ...@@ -23,7 +23,7 @@ namespace graph {
   
namespace minimum_cut { namespace minimum_cut {
   
typedef std::unordered_set<std::pair<node::Node, node::Node> > Cut; typedef ext::unordered_set<std::pair<node::Node, node::Node> > Cut;
   
// Old implementation without templates // Old implementation without templates
using UndirectedGraph = graph::UndirectedGraph<node::Node, edge::CapacityEdge<node::Node, int>>; using UndirectedGraph = graph::UndirectedGraph<node::Node, edge::CapacityEdge<node::Node, int>>;
......
#include <extensions/container/unordered_set.hpp>
/*
* This file is part of Algorithms library toolkit.
* Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
* Algorithms library toolkit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Algorithms library toolkit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <unordered_set>
#include <ext/ostream>
#include <extensions/range.hpp>
namespace ext {
/**
* Class extending the unordered_set class from the standard library. Original reason is to allow printing of the container with overloaded operator <<.
*
* The class mimics the behavior of the unordered_set from the standard library.
*
* \tparam T the type of keys inside the unordered_set
* \tparam Hash the hasher type used to order keys
* \tparam KeyEqual the comparator of keys
*/
template < typename T, typename Hash = std::hash < T >, typename KeyEqual = std::equal_to < T >, typename Alloc = std::allocator < T > >
class unordered_set : public std::unordered_set < T, Hash, KeyEqual, Alloc > {
public:
/**
* Inherit constructors of the standard unordered_set
*/
using std::unordered_set < T, Hash, KeyEqual, Alloc >::unordered_set; // NOLINT(modernize-use-equals-default)
/**
* Inherit operator = of the standard unordered_set
*/
using std::unordered_set < T, Hash, KeyEqual, Alloc >::operator =;
#ifndef __clang__
/**
* Default constructor needed by g++ since it is not inherited
*/
unordered_set ( ) = default;
/**
* Copy constructor needed by g++ since it is not inherited
*/
unordered_set ( const unordered_set & other ) = default;
/**
* Move constructor needed by g++ since it is not inherited
*/
unordered_set ( unordered_set && other ) = default;
/**
* Copy operator = needed by g++ since it is not inherited
*/
unordered_set & operator = ( unordered_set && other ) = default;
/**
* Move operator = needed by g++ since it is not inherited
*/
unordered_set & operator = ( const unordered_set & other ) = default;
#endif
/**
* Constructor from range of values.
*
* \tparam Iterator the type of range iterator
*
* \param range the source range
*/
template < class Iterator >
explicit unordered_set ( const ext::iterator_range < Iterator > & range ) : unordered_set ( range.begin ( ), range.end ( ) ) {
}
/**
* \brief
* Inherited behavior of begin for non-const instance.
*
* \return iterator the first element of unordered_set
*/
auto begin ( ) & {
return std::unordered_set < T, Hash, KeyEqual, Alloc >::begin ( );
}
/**
* \brief
* Inherited behavior of begin for const instance.
*
* \return const_iterator the first element of unordered_set
*/
auto begin ( ) const & {
return std::unordered_set < T, Hash, KeyEqual, Alloc >::begin ( );
}
/**
* \brief
* New variant of begin for rvalues.
*
* \return move_iterator the first element of unordered_set
*/
auto begin ( ) && {
return make_set_move_iterator ( this->begin ( ) );
}
/**
* \brief
* Inherited behavior of end for non-const instance.
*
* \return iterator to one after the last element of unordered_set
*/
auto end ( ) & {
return std::unordered_set < T, Hash, KeyEqual, Alloc >::end ( );
}
/**
* \brief
* Inherited behavior of end for const instance.
*
* \return const_iterator to one after the last element of unordered_set
*/
auto end ( ) const & {
return std::unordered_set < T, Hash, KeyEqual, Alloc >::end ( );
}
/**
* \brief
* New variant of end for rvalues.
*
* \return move_iterator to one after the last element of unordered_set
*/
auto end ( ) && {
return make_set_move_iterator ( this->end ( ) );
}
/**
* \brief
* Make range of non-const begin to end iterators.
*
* \return full range over container values
*/
auto range ( ) & {
auto endIter = end ( );
auto beginIter = begin ( );
return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
}
/**
* \brief
* Make range of non-const begin to end iterators.
*
* \return full range over container values
*/
auto range ( ) const & {
auto endIter = end ( );
auto beginIter = begin ( );
return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
}
/**
* \brief
* Make range of move begin to end iterators.
*
* \return full range over container values
*/
auto range ( ) && {
auto endIter = std::move ( * this ).end ( );
auto beginIter = std::move ( * this ).begin ( );
return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
}
};
/**
* \brief
* Operator to print the unordered_set to the output stream.
*
* \param out the output stream
* \param unordered_set the unordered_set to print
*
* \tparam T the type of keys inside the unordered_set
* \tparam R the type of values inside the unordered_set
* \tparam Ts ... remaining unimportant template parameters of the unordered_set
*
* \return the output stream from the \p out
*/
template< class T, class ... Ts >
ext::ostream& operator<<(ext::ostream& out, const ext::unordered_set<T, Ts ...>& list) {
out << "{";
bool first = true;
for(const T& item : list) {
if(!first) out << ", ";
first = false;
out << item;
}
out << "}";
return out;
}
/**
* \brief
* Implementation of union of two sets.
*
* \tparam T the type of values stored in unioned sets
*
* \param first the first unordered_set to union
* \param second the second unordered_set to union
*
* \return unordered_set representing union
*/
template < class T >
ext::unordered_set < T > operator +( const ext::unordered_set < T > & first, const ext::unordered_set < T > & second ) {
ext::unordered_set < T > res ( first );
res.insert ( second.begin ( ), second.end ( ) );
return res;
}
} /* namespace ext */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment