GeNN  4.9.0
GPU enhanced Neuronal Networks (GeNN)
codeStream.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Standard C++ includes
4 #include <ostream>
5 #include <stdexcept>
6 #include <streambuf>
7 #include <string>
8 #include <vector>
9 
10 // GeNN includes
11 #include "logging.h"
12 #include "gennExport.h"
13 
14 //----------------------------------------------------------------------------
15 // CodeGenerator::CodeStream
16 //----------------------------------------------------------------------------
18 
19 namespace CodeGenerator
20 {
21 class GENN_EXPORT CodeStream : public std::ostream
22 {
23 private:
24  //------------------------------------------------------------------------
25  // IndentBuffer
26  //------------------------------------------------------------------------
27  class IndentBuffer : public std::streambuf
28  {
29  public:
30  IndentBuffer() : m_Sink(NULL), m_NewLine(false), m_IndentLevel(0){}
31 
32  //--------------------------------------------------------------------
33  // Public API
34  //--------------------------------------------------------------------
35  void indent()
36  {
37  m_IndentLevel++;
38  }
39 
40  void deindent()
41  {
42  m_IndentLevel--;
43  }
44 
45  void setSink(std::streambuf *sink)
46  {
47  m_Sink = sink;
48  }
49 
50  private:
51  //--------------------------------------------------------------------
52  // Streambuf overrides
53  //--------------------------------------------------------------------
54  virtual int overflow(int c) override;
55 
56  //----------------------------------------------------------------------------
57  // Members
58  //----------------------------------------------------------------------------
59  std::streambuf *m_Sink;
60  bool m_NewLine;
61  unsigned int m_IndentLevel;
62  };
63 
64 public:
65  //------------------------------------------------------------------------
66  // OB
67  //------------------------------------------------------------------------
69 
71  struct OB
72  {
73  OB(unsigned int level) : Level(level){}
74 
75  const unsigned int Level;
76  };
77 
78  //------------------------------------------------------------------------
79  // CB
80  //------------------------------------------------------------------------
82 
84  struct CB
85  {
86  CB(unsigned int level) : Level(level){}
87 
88  const unsigned int Level;
89  };
90 
91  //------------------------------------------------------------------------
92  // Scope
93  //------------------------------------------------------------------------
94  class Scope
95  {
96  public:
97  Scope(CodeStream &codeStream)
98  : m_CodeStream(codeStream), m_Level(s_NextLevel++)
99  {
100  m_CodeStream << CodeStream::OB(m_Level);
101  }
102 
104  {
105  // If we're not in the middle of handling an uncaught exception
106  if(!std::uncaught_exception()) {
107  try
108  {
109  m_CodeStream << CodeStream::CB(m_Level);
110  }
111  catch(const std::runtime_error &exception)
112  {
113  LOGE_CODE_GEN << exception.what();
114  }
115  }
116  }
117 
118  private:
119  //------------------------------------------------------------------------
120  // Static members
121  //------------------------------------------------------------------------
122  GENN_EXPORT static unsigned int s_NextLevel;
123 
124  //------------------------------------------------------------------------
125  // Members
126  //------------------------------------------------------------------------
127  CodeStream &m_CodeStream;
128  const unsigned int m_Level;
129  };
130 
131  CodeStream(): std::ostream(&m_Buffer) {
132  m_Braces.push_back(0);
133  }
134 
135  CodeStream(std::ostream &stream): CodeStream() {
136  setSink(stream);
137  }
138 
139  void setSink(std::ostream &stream)
140  {
141  m_Buffer.setSink(stream.rdbuf());
142  }
143 
144 private:
145  //------------------------------------------------------------------------
146  // Friends
147  //------------------------------------------------------------------------
148  GENN_EXPORT friend std::ostream& operator << (std::ostream& s, const OB &ob);
149  GENN_EXPORT friend std::ostream& operator << (std::ostream& s, const CB &cb);
150 
151  //------------------------------------------------------------------------
152  // Members
153  //------------------------------------------------------------------------
154  IndentBuffer m_Buffer;
155  std::vector<unsigned int> m_Braces;
156 };
157 
158 //------------------------------------------------------------------------
159 // Operators
160 //------------------------------------------------------------------------
161 GENN_EXPORT std::ostream& operator << (std::ostream& s, const CodeStream::OB &ob);
162 GENN_EXPORT std::ostream& operator << (std::ostream& s, const CodeStream::CB &cb);
163 } // namespace CodeGenerator;
164 
165 
A close bracket marker.
Definition: codeStream.h:84
std::ostream & operator<<(std::ostream &out, const MemAlloc &m)
Definition: backendBase.h:159
~Scope()
Definition: codeStream.h:103
OB(unsigned int level)
Definition: codeStream.h:73
#define GENN_EXPORT
Definition: gennExport.h:13
STL namespace.
An open bracket marker.
Definition: codeStream.h:71
CodeStream(std::ostream &stream)
Definition: codeStream.h:135
void setSink(std::ostream &stream)
Definition: codeStream.h:139
Scope(CodeStream &codeStream)
Definition: codeStream.h:97
Helper class for generating code - automatically inserts brackets, indents etc.
Definition: backendBase.h:30
Definition: codeStream.h:21
CB(unsigned int level)
Definition: codeStream.h:86
const unsigned int Level
Definition: codeStream.h:75
#define LOGE_CODE_GEN
Definition: logging.h:32
const unsigned int Level
Definition: codeStream.h:88
CodeStream()
Definition: codeStream.h:131
Definition: codeStream.h:94