LiuCixin

C++: Tree + traverse + forAll

Nov 1st, 2025 (edited)
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | Source Code | 0 0
  1. #include <vector>
  2. #include <variant>
  3. #include <string>
  4. #include <iostream>
  5. #include "cpp-httplib/httplib.h"
  6.  
  7. const std::string cSite { "http://kit.local" };
  8. const std::string cUrlComment { "/comment/?id=" };
  9.  
  10. using StatusT = httplib::StatusCode;
  11. using ResultT = std::variant<std::string, StatusT>;
  12. using ErrorsList = std::vector<StatusT>;
  13.  
  14. /* define << for ResultT and Node<T> (below) to print results */
  15. static std::ostream& operator <<(std::ostream& os, const ResultT& val) {
  16.   if (const std::string* pval = std::get_if<std::string>(&val))
  17.     std::cout << "'" << *pval << "'";
  18.   else if (const StatusT* code = std::get_if<StatusT>(&val))
  19.     std::cout << "Error " << *code << ": " << httplib::status_message(*code);
  20.   return os;
  21. }
  22.  
  23. /* tree */
  24. template<typename T>
  25. struct Node {
  26.   T value;
  27.   std::vector<Node<T>> children;
  28.   Node() = delete;
  29.   Node(const T& val) : value(val) {}
  30.   void insert(const Node<T>& node)
  31.   {
  32.     if (node.value == value)
  33.       return;
  34.     children.push_back(node);
  35.   }
  36.  
  37.   friend std::ostream& operator <<(std::ostream& os, const Node<T>& val)
  38.   {
  39.     os << "[" << val.value << "]";
  40.     if (!val.children.empty())
  41.       os << "\nChildren:\t";
  42.     std::for_each(val.children.cbegin(), val.children.cend(),
  43.       [&os] (const Node<T> node) { os << node; });
  44.     return os;
  45.   }
  46. };
  47. using CommentTree = Node<ResultT>;
  48.  
  49. template<typename T1, typename T2, typename T3>
  50. Node<T2> traverse(const Node<T1>& src, T3 f) {
  51.   Node<T2> result(f(src.value));
  52.   std::for_each(src.children.cbegin(), src.children.cend(),
  53.     [&] (const Node<T1>& node) {
  54.       result.children.push_back(traverse<T1, T2, T3>(node, f));
  55.     });
  56.   return result;
  57. }
  58.  
  59. template<typename T1, typename T2, typename T3>
  60. void forAll(const Node<T1>& src, std::vector<T2>& result, T3 f) {
  61.   f(src.value, result);
  62.   std::for_each(src.children.cbegin(), src.children.cend(),
  63.     [&] (const Node<T1>& node) {
  64.       forAll<T1, T2, T3>(node, result, f);
  65.     });
  66. }
  67.  
  68. static ResultT tryGetContent(httplib::Client& c, const int x) {
  69.   auto res = c.Get(cUrlComment + std::to_string(x));
  70.   if (res->status == StatusT::OK_200)
  71.     return res->body;
  72.   return static_cast<StatusT>(res->status);
  73. }
  74.  
  75. static std::variant<CommentTree, ErrorsList>
  76.     tryGetContent(const Node<int>& src) {
  77.   httplib::Client cli(cSite);
  78.  
  79.   auto actionGet = [&] (const int x) {
  80.     return tryGetContent(cli, x);
  81.   };
  82.   CommentTree result = traverse<int, ResultT, decltype(actionGet)>(src, actionGet);
  83.  
  84.   ErrorsList errors;
  85.   auto collectErrors = [&] (const CommentTree& node, ErrorsList& list) {
  86.     if (const StatusT* code = std::get_if<StatusT>(&node.value))
  87.       list.push_back(*code);
  88.   };
  89.   forAll<ResultT, StatusT, decltype(collectErrors)>(result, errors, collectErrors);
  90.  
  91.   if (!errors.empty())
  92.     return errors;
  93.   return result;
  94. }
  95.  
  96. int main() {
  97.   using IntNode = Node<int>;
  98.  
  99.   IntNode tree { 10 };
  100.   IntNode a { 100 }, b { 101 }, c { 102 };
  101.   IntNode bb { 1001 };
  102.   b.insert(bb);
  103.  
  104.   tree.insert(a);
  105.   tree.insert(b);
  106.   tree.insert(c);
  107.  
  108.   IntNode root { 1 };
  109.   root.insert(tree);
  110.   std::cout << "\n Source:\n";
  111.   std::cout << root;
  112.  
  113.   auto result = tryGetContent(root);
  114.  
  115.   /* print result */
  116.   if (const auto* list = std::get_if<ErrorsList>(&result)) {
  117.     std::for_each(list->cbegin(), list->cend(), [&](const StatusT code) {
  118.       std::cout << "\nError " << code << ": " << httplib::status_message(code);
  119.     });
  120.   } else if (const auto* node = std::get_if<CommentTree>(&result)) {
  121.     std::cout << "\n Result:\n";
  122.     std::cout << *node;
  123.   }
  124.   return 0;
  125. }
  126.  
Advertisement
Add Comment
Please, Sign In to add comment