1 /* Copyright (c) 1997-2021
2    Ewgenij Gawrilow, Michael Joswig, and the polymake team
3    Technische Universität Berlin, Germany
4    https://polymake.org
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version: http://www.gnu.org/licenses/gpl.txt.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 --------------------------------------------------------------------------------
16 */
17 
18 #pragma once
19 
20 #include "polymake/Graph.h"
21 #include "polymake/Array.h"
22 #include "polymake/graph/Decoration.h"
23 
24 namespace polymake { namespace graph {
25 
26 /*
27  * This iterator is used for converting the old DIMS array of HasseDiagram/FaceLattice to the new
28  * InverseRankMap. It iterates over pairs (rank, list of node of this rank).
29  */
30 template <typename SeqType>
31 class dim_to_rank_iterator {
32 public:
33   using iterator_category = std::forward_iterator_tag;
34   using value_type = std::pair<Int, typename SeqType::map_value_type>;
35   using reference = const value_type&;
36   using pointer = const value_type*;
37   using difference_type = ptrdiff_t;
38 
dim_to_rank_iterator(Int total_rank_,Int total_size_,bool built_dually_,const Array<Int> & dims_)39   dim_to_rank_iterator(Int total_rank_, Int total_size_, bool built_dually_, const Array<Int>& dims_)
40     : total_rank(total_rank_)
41     , total_size(total_size_)
42     , built_dually(built_dually_)
43     , dims(dims_)
44     , current_dims_index(0)
45     , current_index_bound(0)
46   {
47     if (!dims.empty()) current_index_bound = dims[0];
48     result = std::make_pair(built_dually ? total_rank : 0,
49                             SeqType::make_map_value_type(0, std::max(current_index_bound, 1L)-1));
50   }
51 
52   reference operator* () const { return result; }
53   pointer operator->() const { return &result; }
54 
55   dim_to_rank_iterator& operator++ () { find_next(); return *this; }
56   const dim_to_rank_iterator operator++ (int) { dim_to_rank_iterator copy = *this; operator++(); return copy; }
57 
at_end()58   bool at_end() const { return current_dims_index > dims.size(); }
59 
60 protected:
find_next()61   void find_next()
62   {
63     ++current_dims_index;
64     if (!at_end()) {
65       Int old_index_bound = current_index_bound;
66       current_index_bound = current_dims_index == dims.size()? total_size : dims[current_dims_index];
67       Int next_rank = result.first + (built_dually? -1 : 1);
68       result = std::make_pair(next_rank,
69                               SeqType::make_map_value_type(old_index_bound, current_index_bound-1));
70     }
71   }
72 
73   const Int total_rank;
74   const Int total_size;
75   const bool built_dually;
76   const Array<Int>& dims;
77   Int current_dims_index;
78   Int current_index_bound;
79   value_type result;
80 };
81 
82 /*
83  * @brief Computes a NodeMap which only contains the face of nodes.
84  */
85 template <typename Decoration>
86 NodeMap<Directed, Set<Int>>
faces_map_from_decoration(const Graph<Directed> & graph,const NodeMap<Directed,Decoration> & decor)87 faces_map_from_decoration(const Graph<Directed>& graph, const NodeMap<Directed, Decoration>& decor)
88 {
89   return NodeMap<Directed, Set<Int>>(
90            graph,
91            entire(attach_member_accessor(decor, ptr2type<Decoration, Set<Int>, &Decoration::face>()))
92          );
93 }
94 
95 } }
96 
97