hmbdc
simplify-high-performance-messaging-programming
LfbStream.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 #include "hmbdc/Exception.hpp"
4 #include <memory>
5 #include <thread>
6 #include <iostream>
7 #include <string.h>
8 #include <stdexcept>
9 #include <type_traits>
10 
11 namespace hmbdc { namespace text {
12 
13 namespace lfb_stream {
14 
15 struct Streamable{
16  virtual void dump(std::ostream& os) const = 0;
17  virtual ~Streamable(){}
18 } __attribute__ ((__may_alias__));
19 
20 namespace lfbstream_detail {
21 
22 template <uint32_t SIZE_LIMIT, typename T>
24 : Streamable {
25  TypedStreamable(T&& m)
26  : payload(std::forward<T>(m)){}
27  typename std::remove_reference<T>::type payload;
28  virtual void dump(std::ostream& os) const {os << payload;}
29 }__attribute__ ((__may_alias__));
30 
31 template<uint32_t SIZE_LIMIT, std::size_t N >
32 struct TypedStreamable<SIZE_LIMIT, const char (&) [N]>
33 : Streamable {
34 private:
35  const char * payload;
36 public:
37  TypedStreamable(char const* s)
38  : payload(s){}
39  virtual void dump(std::ostream& os) const {os << payload;}
40 }__attribute__ ((__may_alias__));
41 
42 template<uint32_t SIZE_LIMIT, std::size_t N >
43 struct TypedStreamable<SIZE_LIMIT, const char [N]>
44 : Streamable {
45 private:
46  const char * payload;
47 public:
48  TypedStreamable(char const* s)
49  : payload(s){}
50  virtual void dump(std::ostream& os) const {os << payload;}
51 }__attribute__ ((__may_alias__));
52 
53 template<uint32_t SIZE_LIMIT, std::size_t N >
54 struct TypedStreamable<SIZE_LIMIT, char (&) [N]>
55 : Streamable {
56 private:
57  char payload[SIZE_LIMIT - sizeof(Streamable)];
58 public:
59  TypedStreamable(char const* s) {
60  strncpy(payload, s, sizeof(payload));
61  payload[sizeof(payload) - 1] = 0;
62  }
63  virtual void dump(std::ostream& os) const {os << payload;}
64 }__attribute__ ((__may_alias__));
65 
66 template <uint32_t SIZE_LIMIT>
67 struct TypedStreamable<SIZE_LIMIT, char const*>
68 : Streamable {
69 private:
70  char payload[SIZE_LIMIT - sizeof(Streamable)];
71 public:
72  TypedStreamable(char const* m) {
73  strncpy(payload, m, sizeof(payload));
74  payload[sizeof(payload) - 1] = 0;
75  }
76  virtual void dump(std::ostream& os) const {os << payload;}
77 }__attribute__ ((__may_alias__));
78 
79 } // lfbstream_detail
80 
81 template <typename Buffer, typename BufferItem, uint32_t STREAMABLE_TYPE_TAG>
82 struct OStringStream {
83 private:
85  using BufItem = typename Buffer::value_type;
86  enum {
87  PAYLOAD_SIZE = sizeof(BufferItem::payload),
88  };
89 
90 public:
91 
92  OStringStream(Buffer& q)
93  : buffer_(q){
94  if (q.maxItemSize() < sizeof(BufferItem)) {
95  HMBDC_THROW(std::out_of_range,
96  "buffer not able to hold item " << q.maxItemSize() << '<' << sizeof(BufferItem));
97  }
98  }
99 
100  virtual ~OStringStream(){}
101 
102  Buffer& buf() { return buffer_;}
103  Buffer const & buf() const { return buffer_;}
104 
105  template <typename ...Args>
106  ThisT& operator()(Args&&... args) {
107  auto sz = sizeof...(Args);
108  auto it = buffer_.claim(sz);
109  stream(it, std::forward<Args>(args)...);
110  buffer_.commit(it, sz);
111  return *this;
112  }
113 
114  template <typename Message>
115  static void dump(std::ostream& os, Message& m, bool callStreamableDtor = true) {
116  auto ptr = reinterpret_cast<Streamable*>(m.payload);
117  ptr->dump(os);
118  if (callStreamableDtor) ptr->~Streamable();
119  }
120 
121 private:
122  template <typename Arg, typename ...Args>
123  void stream(typename Buffer::iterator it, Arg&& arg, Args&&... args) {
125  static_assert(sizeof(Actual) <= PAYLOAD_SIZE, "one of item too big");
126  auto ptr = static_cast<BufferItem*>(*it);
127  ptr->typeTag = STREAMABLE_TYPE_TAG;
128  new (&ptr->payload) Actual(std::forward<Arg>(arg));
129  stream(++it, std::forward<Args>(args)...);
130  }
131  void stream(typename Buffer::iterator) {}
132 
133  Buffer& buffer_;
134 };
135 
136 }}}
Definition: LfbStream.hpp:15
Definition: LfbStream.hpp:82
Definition: Base.hpp:13