Libftpp
A modern C++ library
thread_safe_iostream.hpp
Go to the documentation of this file.
1 #ifndef THREAD_SAFE_IOSTREAM
2 #define THREAD_SAFE_IOSTREAM
3 
4 #include <iostream>
5 #include <limits>
6 #include <mutex>
7 #include <sstream>
8 #include <string>
9 
31 {
32 private:
33  static std::mutex _mutex;
34  std::ostringstream _buffer;
35  std::string _prefix;
36  void flushBuffer();
37 
38 public:
39  template <typename T>
41  {
42  std::lock_guard<std::mutex> lock(_mutex);
43  while (1)
44  {
45  std::cin >> value;
46  if (std::cin.fail())
47  {
48  std::cout << "Invalid input !" << std::endl;
49  std::cin.clear();
50 
51  // Vide completement le buffer (limits.h)
52  std::cin.ignore(INT32_MAX, '\n');
53  continue;
54  }
55  break;
56  }
57  return *this;
58  }
59 
60  ThreadSafeIOStream& operator<<(std::ostream& (*funct)(std::ostream&));
61 
62  template <typename T>
63  ThreadSafeIOStream& operator<<(const T& value)
64  {
65  _buffer << value;
66 
67  std::string line = _buffer.str();
68  std::string::size_type pos = 0;
69  std::string::size_type cursor = 0;
70  if (line.find('\n') == std::string::npos)
71  return *this;
72 
73  std::lock_guard<std::mutex> lock(_mutex);
74 
75  while ((pos = line.find('\n', cursor)) != std::string::npos)
76  {
77  std::cout << _prefix;
78  std::cout << line.substr(cursor, pos - cursor) << '\n';
79  cursor = pos + 1;
80  }
81 
82  _buffer.clear();
83  _buffer.str("");
84  if (cursor < line.length())
85  std::cout << line.substr(cursor);
86  return *this;
87  }
88 
89  void setPrefix(const std::string& prefix);
90 
91  template <typename T>
92  void prompt(const std::string& question, T& dest)
93  {
94  {
95  std::lock_guard<std::mutex> lock(_mutex);
96  std::cout << question;
97  }
98  *this >> dest;
99  }
100 };
101 
102 extern thread_local ThreadSafeIOStream threadSafeCout;
103 
104 #endif
Thread-Safe I/O Stream.
void setPrefix(const std::string &prefix)
void prompt(const std::string &question, T &dest)
ThreadSafeIOStream & operator<<(std::ostream &(*funct)(std::ostream &))
ThreadSafeIOStream & operator<<(const T &value)
ThreadSafeIOStream & operator>>(T &value)
thread_local ThreadSafeIOStream threadSafeCout