| 
									
										
										
										
											2020-03-14 17:18:06 -07:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | #include <cstddef>
 | 
					
						
							|  |  |  | #include <queue>
 | 
					
						
							|  |  |  | #include <set>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <map>
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using function = std::string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct group { | 
					
						
							|  |  |  |     std::set<function> members; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using group_ptr = std::unique_ptr<group>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class function_graph { | 
					
						
							|  |  |  |     using group_id = size_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct group_data { | 
					
						
							|  |  |  |         std::set<function> functions; | 
					
						
							|  |  |  |         std::set<group_id> adjacency_list; | 
					
						
							|  |  |  |         size_t indegree; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     using data_ptr = std::shared_ptr<group_data>; | 
					
						
							| 
									
										
										
										
											2020-03-14 21:04:13 -07:00
										 |  |  |     using edge = std::pair<function, function>; | 
					
						
							| 
									
										
										
										
											2020-03-14 17:18:06 -07:00
										 |  |  |     using group_edge = std::pair<group_id, group_id>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::map<function, std::set<function>> adjacency_lists; | 
					
						
							|  |  |  |     std::set<edge> edges; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::set<edge> compute_transitive_edges(); | 
					
						
							|  |  |  |     void create_groups( | 
					
						
							|  |  |  |             const std::set<edge>&, | 
					
						
							|  |  |  |             std::map<function, group_id>&, | 
					
						
							|  |  |  |             std::map<group_id, data_ptr>&); | 
					
						
							|  |  |  |     void create_edges( | 
					
						
							|  |  |  |             std::map<function, group_id>&, | 
					
						
							|  |  |  |             std::map<group_id, data_ptr>&); | 
					
						
							|  |  |  |     std::vector<group_ptr> generate_order( | 
					
						
							|  |  |  |             std::map<function, group_id>&, | 
					
						
							|  |  |  |             std::map<group_id, data_ptr>&); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2020-03-24 22:00:09 -07:00
										 |  |  |     std::set<function>& add_function(const function& f); | 
					
						
							| 
									
										
										
										
											2020-03-14 17:18:06 -07:00
										 |  |  |     void add_edge(const function& from, const function& to); | 
					
						
							|  |  |  |     std::vector<group_ptr> compute_order(); | 
					
						
							|  |  |  | }; |