#include "../Graph.h" namespace TinySTL{ namespace Detail{ template typename graph::node_type graph::make_node(const Index& index, const Value& val){ return node_type(index, val); } template typename const graph::node_type& graph::get_node(const Index& index){ for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) return pair.first; } static node_type empty_node; return empty_node; } template bool graph::is_contained(const Index& index){ for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) return true; } return false; } template typename graph::nodes_set_type graph::empty_node_set(){ return nodes_set_type(); } template bool graph::empty()const{ return nodes_.empty(); } template typename graph::inner_iterator graph::begin(const Index& index){ for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) return inner_iterator(this, (pair.second).begin()); } return end(index); } template typename graph::inner_iterator graph::end(const Index& index){ for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) return inner_iterator(this, (pair.second).end()); } return inner_iterator(); } template typename graph::iterator graph::begin(){ return iterator(this, nodes_.begin()); } template typename graph::iterator graph::end(){ return iterator(this, nodes_.end()); } template size_t graph::size()const{ return size_; } template typename graph::nodes_set_type graph::adjacent_nodes(const Index& index){ nodes_set_type s; for (auto it = begin(index); it != end(index); ++it){ s.push_back(*it); } return s; } template typename graph::nodes_set_type graph::adjacent_nodes(const node_type& n){ return adjacent_nodes(n.first); } template void graph::_DFS(node_type& node, visiter_func_type func, Unordered_set, EqualFunc>& visited){ auto nodes = adjacent_nodes(node.first); func(node); visited.insert(node.first); for (auto& n : nodes){ if (visited.count(n.first) == 0)//has not visited _DFS(n, func, visited); } } template void graph::DFS(const Index& index, visiter_func_type func){ node_type start = (get_node(index)); Unordered_set, EqualFunc> visited(7); _DFS(start, func, visited); } template void graph::_BFS(node_type& node, visiter_func_type func, Unordered_set, EqualFunc>& visited){ auto nodes = adjacent_nodes(node.first); func(node); visited.insert(node.first); do{ nodes_set_type temp; for (auto it = nodes.begin(); it != nodes.end(); ++it){ if (visited.count(it->first) == 0){//has not visited func(*it); visited.insert(it->first); auto s = adjacent_nodes(it->first); temp.insert(temp.end(), s.begin(), s.end()); } } nodes = temp; } while (!nodes.empty()); } template void graph::BFS(const Index& index, visiter_func_type func){ node_type start = (get_node(index)); Unordered_set, EqualFunc> visited(7); _BFS(start, func, visited); } template string graph::to_string(){ string str; std::ostringstream oss; for (auto oit = begin(); oit != end(); ++oit){ oss << "[" << oit->first << "," << oit->second << "]" << ":"; auto eit = end(oit->first); for (auto iit = begin(oit->first); iit != eit; ++iit){ oss << "[" << iit->first << "," << iit->second << "]" << "->"; } oss << "[nil]" << std::endl << std::setw(4) << "|" << std::endl; } oss << "[nil]" << std::endl; str.append(oss.str().c_str()); return str; } template typename graph::equal_func_type graph::get_equal_func()const{ return equal_func; } //******************************************************************************** template inner_iterator& inner_iterator::operator ++(){ ++inner_it_; return *this; } template const inner_iterator inner_iterator::operator ++(int){ auto temp = *this; ++*this; return temp; } template bool operator ==(const inner_iterator& lhs, const inner_iterator& rhs){ return lhs.container_ == rhs.container_ && lhs.inner_it_ == rhs.inner_it_; } template bool operator !=(const inner_iterator& lhs, const inner_iterator& rhs){ return !(lhs == rhs); } //********************************************************************************* template outter_iterator& outter_iterator::operator ++(){ ++outter_it_; return *this; } template const outter_iterator outter_iterator::operator ++(int){ auto temp = *this; ++*this; return temp; } template bool operator ==(const outter_iterator& lhs, const outter_iterator& rhs){ return lhs.container_ == rhs.container_ && lhs.outter_it_ == rhs.outter_it_; } template bool operator !=(const outter_iterator& lhs, const outter_iterator& rhs){ return !(lhs == rhs); } }//end of Detail template directed_graph::directed_graph():graph(){} template void directed_graph::add_node_helper(const Index& index, const nodes_set_type& nodes){ if (nodes.empty()) return; //find node n's list list* l; for (auto& pair : nodes_){ if (equal_func(pair.first.first, index)) l = &(pair.second); } for (const auto& item : nodes){ l->push_front(item); if (!is_contained(item.first)){ add_node(item, empty_node_set()); } } } template void directed_graph::add_node(const node_type& n, const nodes_set_type& nodes){ if (!is_contained(n.first)){ nodes_.push_front(make_pair(n, list())); ++size_; } add_node_helper(n.first, nodes); } template void directed_graph::add_node(const Index& index, const nodes_set_type& nodes){ add_node_helper(index, nodes); } template void directed_graph::delete_node(const Index& index){ for (auto oit = nodes_.begin(); oit != nodes_.end();){ auto& l = oit->second; if (equal_func((oit->first).first, index)){ oit = nodes_.erase(oit); }else{ for (auto iit = l.begin(); iit != l.end();){ if (equal_func(iit->first, index)) iit = l.erase(iit); else ++iit; } ++oit; } } } template void directed_graph::delete_node(const node_type& item){ delete_node(item.first); } template void directed_graph::make_edge(const Index& index1, const Index& index2){ auto node1 = get_node(index1), node2 = get_node(index2); for (auto it = nodes_.begin(); it != nodes_.end(); ++it){ if (equal_func((it->first).first, index1)) (it->second).push_front(node2); } } }