Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.98 KB | None | 0 0
  1. // Example program
  2. #include <exception>
  3. #include <iostream>
  4. #include <stdexcept>
  5. #include <string>
  6. #include <type_traits>
  7. #include <vector>
  8.  
  9. #define ENABLE_PRINT
  10.  
  11. template<typename S, typename T>
  12. class is_streamable
  13. {
  14.   template<typename SS, typename TT>
  15.   static auto test(int)
  16.   -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
  17.  
  18.   template<typename, typename>
  19.   static auto test(...) -> std::false_type;
  20.  
  21. public:
  22.   static const bool value = decltype(test<S,T>(0))::value;
  23. };
  24.  
  25.  
  26. template <typename T> class Stack {
  27. public:
  28.   using PrintFnc = std::function<std::ostream &(std::ostream &stream, const T &)>;
  29.   T top() {
  30.     if (size() == 0) {
  31.       throw std::runtime_error("Stack is empty");
  32.     }
  33.     return data.back();
  34.   }
  35.  
  36.   void pop() {
  37.     if (size() != 0) {
  38.       data.erase(data.end() - 1);
  39.     }
  40.   }
  41.  
  42.   template <typename... Args>
  43.   typename std::enable_if<std::is_constructible<T, Args...>::value, void>::type
  44.   push(Args &&... args) {
  45.     data.emplace_back(args...);
  46.   }
  47.  
  48.   std::size_t size() const { return data.size(); }
  49.  
  50.   template <typename U = T, class = typename std::enable_if<is_streamable<std::ostream, U>::value>::type>
  51.   void print() {
  52.     print(data.size());
  53.   }
  54.   template <typename U = T, class = typename std::enable_if<
  55.                                is_streamable<std::ostream, U>::value>::type>
  56.   void print(std::size_t elementCount) {
  57.     impl_print(elementCount);
  58.   }
  59.  
  60.   template <typename U = T, class = typename std::enable_if<!is_streamable<std::ostream, U>::value>::type>
  61.   void print(PrintFnc printFnc) {
  62.     print(data.size(), printFnc);
  63.   }
  64.   template <typename U = T, class = typename std::enable_if<! is_streamable<std::ostream, U>::value>::type>
  65.   void print(std::size_t elementCount, PrintFnc printFnc) {
  66.     impl_print(elementCount, printFnc);
  67.   }
  68.  
  69. private:
  70.   std::vector<T> data;
  71.  
  72.   void impl_print(
  73.       std::size_t elementCount,
  74.       PrintFnc format =
  75.           [](std::ostream &stream, const auto &val) -> std::ostream & {
  76.         return stream << val;
  77.       }) {
  78.     for (auto iter = data.crbegin(); iter < data.crbegin() + elementCount;
  79.          ++iter) {
  80.       format(std::cout, *iter) << std::endl;
  81.     }
  82.   }
  83. };
  84.  
  85. class Test {
  86. public:
  87.   explicit Test(int a) : a(a), b(a) {}
  88.   Test(int a, int b) : a(a), b(b) {}
  89.  
  90.   int a, b;
  91.  
  92. #ifdef ENABLE_PRINT
  93.   friend std::ostream &operator<<(std::ostream &stream, Test t) {
  94.     return stream << "Test: " << t.a << ", " << t.b;
  95.   }
  96. #endif
  97. };
  98.  
  99. int main() {
  100.   Stack<Test> stack;
  101.   std::cout << stack.size() << std::endl;
  102.   stack.push(Test(10));
  103.   stack.push(20);
  104.   long test = 1000;
  105.   stack.push(test);
  106.   stack.push(20, 1000);
  107.   try {
  108.     std::cout << stack.size() << std::endl;
  109. #ifdef ENABLE_PRINT
  110.     stack.print();
  111. #else
  112.     stack.print([](std::ostream &stream, const Test &t)->std::ostream &{return stream << t.a << " " << t.b;});
  113. #endif
  114.   } catch (std::exception &e) {
  115.     std::cout << e.what() << std::endl;
  116.   }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement