KiCad PCB EDA Suite
sexpr.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Mark Roszko <mark.roszko@gmail.com>
3  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef SEXPR_H_
20 #define SEXPR_H_
21 
22 #include <cstdint>
23 #include <string>
24 #include <vector>
25 #include "sexpr/isexprable.h"
26 #include "sexpr/sexpr_exception.h"
27 
28 
29 namespace SEXPR
30 {
31  using std::int32_t;
32  using std::int64_t;
33 
34  enum class SEXPR_TYPE : char
35  {
41  };
42 
43  typedef std::vector< class SEXPR * > SEXPR_VECTOR;
44 
45  class SEXPR
46  {
47  public:
48  virtual ~SEXPR() {};
49  bool IsList() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_LIST; }
50  bool IsSymbol() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL; }
51  bool IsString() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING; }
52  bool IsDouble() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE; }
53  bool IsInteger() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER; }
54  void AddChild( SEXPR* aChild );
55  SEXPR_VECTOR const * GetChildren() const;
56  SEXPR * GetChild( size_t aIndex ) const;
57  size_t GetNumberOfChildren() const;
58  int64_t GetLongInteger() const;
59  int32_t GetInteger() const;
60  float GetFloat() const;
61  double GetDouble() const;
62  std::string const & GetString() const;
63  std::string const & GetSymbol() const;
64  SEXPR_LIST* GetList();
65  std::string AsString( size_t aLevel = 0) const;
66  size_t GetLineNumber() const { return m_lineNumber; }
67 
68  protected:
70  SEXPR( SEXPR_TYPE aType, size_t aLineNumber );
71  SEXPR( SEXPR_TYPE aType );
72  size_t m_lineNumber;
73  };
74 
75  struct SEXPR_INTEGER : public SEXPR
76  {
77  int64_t m_value;
78 
79  SEXPR_INTEGER( int64_t aValue ) :
81 
82  SEXPR_INTEGER( int64_t aValue, int aLineNumber ) :
83  SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER, aLineNumber ), m_value( aValue ) {};
84  };
85 
86  struct SEXPR_DOUBLE : public SEXPR
87  {
88  double m_value;
89 
90  SEXPR_DOUBLE( double aValue ) :
92 
93  SEXPR_DOUBLE( double aValue, int aLineNumber ) :
94  SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE, aLineNumber ), m_value( aValue ) {};
95  };
96 
97  struct SEXPR_STRING : public SEXPR
98  {
99  std::string m_value;
100 
101  SEXPR_STRING( const std::string& aValue ) :
103 
104  SEXPR_STRING( const std::string& aValue, int aLineNumber ) :
105  SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING, aLineNumber ), m_value( aValue ) {};
106  };
107 
108  struct SEXPR_SYMBOL : public SEXPR
109  {
110  std::string m_value;
111 
112  SEXPR_SYMBOL( const std::string& aValue ) :
114 
115  SEXPR_SYMBOL( const std::string& aValue, int aLineNumber ) :
116  SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL, aLineNumber ), m_value( aValue ) {};
117  };
118 
119  struct _OUT_STRING
120  {
121  bool _Symbol;
122  const std::string& _String;
123  };
124 
125  inline _OUT_STRING AsSymbol( const std::string& aString )
126  {
127  struct _OUT_STRING ret = { true, aString };
128  return ret;
129  }
130 
131  inline _OUT_STRING AsString( const std::string& aString )
132  {
133  struct _OUT_STRING ret = { false, aString };
134  return ret;
135  }
136 
137  struct _IN_STRING
138  {
139  bool _Symbol;
140  std::string& _String;
141  };
142 
143  inline _IN_STRING AsSymbol( std::string& aString )
144  {
145  struct _IN_STRING ret = { true, aString };
146  return ret;
147  }
148 
149  inline _IN_STRING AsString( std::string& aString )
150  {
151  struct _IN_STRING ret = { false, aString };
152  return ret;
153  }
154 
156  {
157  public:
158  SEXPR_SCAN_ARG( int32_t* aValue ) :
159  type( Type::INT ) { u.int_value = aValue; }
160 
161  SEXPR_SCAN_ARG( int64_t* aValue ) :
162  type( Type::LONGINT ) { u.lint_value = aValue; }
163 
164  SEXPR_SCAN_ARG( double* aValue ) :
165  type( Type::DOUBLE ) { u.dbl_value = aValue; }
166 
167  SEXPR_SCAN_ARG( std::string* aValue ) :
168  type( Type::STRING ) { u.str_value = aValue; }
169 
171  type( Type::SEXPR_STRING ) { u.sexpr_str = &aValue; }
172 
173  SEXPR_SCAN_ARG( const std::string* aValue ) :
174  type( Type::STRING_COMP ) { str_value = *aValue; }
175 
176  SEXPR_SCAN_ARG( std::string aValue ) :
177  type( Type::STRING_COMP ) { str_value = aValue; }
178 
179  SEXPR_SCAN_ARG( const char* aValue ) :
180  type( Type::STRING_COMP ) { str_value = aValue; }
181 
182  private:
183  friend class SEXPR_LIST;
184 
185  enum class Type : char { INT, DOUBLE, STRING, LONGINT, STRING_COMP, SEXPR_STRING };
187 
188  union
189  {
190  int64_t* lint_value;
191  int32_t* int_value;
192  double* dbl_value;
193  std::string* str_value;
195  } u;
196 
197  std::string str_value;
198  };
199 
201  {
202  public:
203  SEXPR_CHILDREN_ARG( int32_t aValue ) :
204  type( Type::INT ) { u.int_value = aValue; }
205 
206  SEXPR_CHILDREN_ARG( int64_t aValue ) :
207  type( Type::LONGINT ) { u.lint_value = aValue; }
208 
209  SEXPR_CHILDREN_ARG( double aValue ) :
210  type( Type::DOUBLE ) { u.dbl_value = aValue; }
211 
212  SEXPR_CHILDREN_ARG( const std::string& aValue ) :
213  type( Type::STRING ) { str_value = aValue; }
214 
215  SEXPR_CHILDREN_ARG( const char* aValue ) :
216  type( Type::STRING ) { str_value = aValue; }
217 
218  SEXPR_CHILDREN_ARG( const _OUT_STRING& aValue ) :
219  type( Type::SEXPR_STRING ) { str_value = aValue._String; u.symbol = aValue._Symbol; }
220 
221  SEXPR_CHILDREN_ARG( SEXPR* aPointer ) :
222  type( Type::SEXPR_ATOM ) { u.sexpr_ptr = aPointer; }
223 
224  private:
225  friend class SEXPR_LIST;
226 
227  enum class Type : char { INT, DOUBLE, STRING, LONGINT, SEXPR_STRING, SEXPR_ATOM };
229 
230  union
231  {
232  int64_t lint_value;
233  int32_t int_value;
234  double dbl_value;
236  bool symbol;
237  } u;
238 
239  std::string str_value;
240  };
241 
242  class SEXPR_LIST : public SEXPR
243  {
244  public:
246 
247  SEXPR_LIST( int aLineNumber ) :
248  SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST, aLineNumber), m_inStreamChild( 0 ) {};
249 
250  template <typename... Args>
251  SEXPR_LIST( const Args&... args ) :
253  {
254  AddChildren(args...);
255  };
256 
258 
259  template <typename... Args>
260  size_t Scan( const Args&... args )
261  {
262  SEXPR_SCAN_ARG arg_array[] = { args... };
263  return doScan( arg_array, sizeof...( Args ) );
264  }
265 
266  template <typename... Args>
267  void AddChildren( const Args&... args )
268  {
269  SEXPR_CHILDREN_ARG arg_array[] = { args... };
270  doAddChildren( arg_array, sizeof...( Args ) );
271  }
272 
273  virtual ~SEXPR_LIST();
274 
275  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, double value );
276  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, float value );
277  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int64_t value );
278  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int32_t value );
279  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, std::string value );
280  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const _OUT_STRING setting );
281  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const ISEXPRABLE& obj );
282  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR_LIST* list2 );
283  friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR* obj );
284  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, ISEXPRABLE& obj );
285  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, std::string& str );
286  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int32_t& inte );
287  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int64_t& inte );
288  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, float& inte );
289  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, double& inte );
290  friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, const _IN_STRING is );
291 
292  private:
294  size_t doScan( const SEXPR_SCAN_ARG *args, size_t num_args );
295  void doAddChildren( const SEXPR_CHILDREN_ARG *args, size_t num_args );
296  };
297 
298 } // namespace SEXPR
299 
300 #endif
std::vector< class SEXPR * > SEXPR_VECTOR
Definition: sexpr.h:43
bool IsString() const
Definition: sexpr.h:51
SEXPR_SCAN_ARG(int32_t *aValue)
Definition: sexpr.h:158
SEXPR_CHILDREN_ARG(const char *aValue)
Definition: sexpr.h:215
union SEXPR::SEXPR_CHILDREN_ARG::@36 u
bool IsSymbol() const
Definition: sexpr.h:50
SEXPR_SCAN_ARG(std::string aValue)
Definition: sexpr.h:176
SEXPR_DOUBLE(double aValue)
Definition: sexpr.h:90
SEXPR_INTEGER(int64_t aValue, int aLineNumber)
Definition: sexpr.h:82
size_t m_lineNumber
Definition: sexpr.h:72
size_t GetLineNumber() const
Definition: sexpr.h:66
double * dbl_value
Definition: sexpr.h:192
std::string m_value
Definition: sexpr.h:110
std::string m_value
Definition: sexpr.h:99
size_t doScan(const SEXPR_SCAN_ARG *args, size_t num_args)
Definition: sexpr.cpp:407
SEXPR_LIST(int aLineNumber)
Definition: sexpr.h:247
bool IsList() const
Definition: sexpr.h:49
friend SEXPR_LIST & operator<<(SEXPR_LIST &list, double value)
Definition: sexpr.cpp:241
SEXPR_TYPE m_type
Definition: sexpr.h:69
const std::string & _String
Definition: sexpr.h:122
bool IsDouble() const
Definition: sexpr.h:52
int64_t m_value
Definition: sexpr.h:77
SEXPR_VECTOR m_children
Definition: sexpr.h:255
int m_inStreamChild
Definition: sexpr.h:293
void doAddChildren(const SEXPR_CHILDREN_ARG *args, size_t num_args)
Definition: sexpr.cpp:484
SEXPR_CHILDREN_ARG(double aValue)
Definition: sexpr.h:209
void AddChildren(const Args &... args)
Definition: sexpr.h:267
SEXPR_CHILDREN_ARG(int32_t aValue)
Definition: sexpr.h:203
SEXPR_DOUBLE(double aValue, int aLineNumber)
Definition: sexpr.h:93
SEXPR_SCAN_ARG(int64_t *aValue)
Definition: sexpr.h:161
double m_value
Definition: sexpr.h:88
SEXPR_CHILDREN_ARG(SEXPR *aPointer)
Definition: sexpr.h:221
virtual ~SEXPR_LIST()
Definition: sexpr.cpp:205
SEXPR_STRING(const std::string &aValue)
Definition: sexpr.h:101
size_t Scan(const Args &... args)
Definition: sexpr.h:260
_OUT_STRING AsString(const std::string &aString)
Definition: sexpr.h:131
_OUT_STRING AsSymbol(const std::string &aString)
Definition: sexpr.h:125
SEXPR_SYMBOL(const std::string &aValue, int aLineNumber)
Definition: sexpr.h:115
SEXPR_INTEGER(int64_t aValue)
Definition: sexpr.h:79
SEXPR_CHILDREN_ARG(int64_t aValue)
Definition: sexpr.h:206
SEXPR_CHILDREN_ARG(const _OUT_STRING &aValue)
Definition: sexpr.h:218
SEXPR_SCAN_ARG(double *aValue)
Definition: sexpr.h:164
friend SEXPR_LIST & operator>>(SEXPR_LIST &input, ISEXPRABLE &obj)
Definition: sexpr.cpp:277
SEXPR_SCAN_ARG(_IN_STRING &aValue)
Definition: sexpr.h:170
SEXPR_LIST(const Args &... args)
Definition: sexpr.h:251
SEXPR_SCAN_ARG(const std::string *aValue)
Definition: sexpr.h:173
std::string str_value
Definition: sexpr.h:239
SEXPR_TYPE
Definition: sexpr.h:34
SEXPR_SCAN_ARG(const char *aValue)
Definition: sexpr.h:179
SEXPR_STRING(const std::string &aValue, int aLineNumber)
Definition: sexpr.h:104
int32_t * int_value
Definition: sexpr.h:191
SEXPR_SCAN_ARG(std::string *aValue)
Definition: sexpr.h:167
std::string & _String
Definition: sexpr.h:140
std::string str_value
Definition: sexpr.h:197
SEXPR_SYMBOL(const std::string &aValue)
Definition: sexpr.h:112
bool IsInteger() const
Definition: sexpr.h:53
virtual ~SEXPR()
Definition: sexpr.h:48
int64_t * lint_value
Definition: sexpr.h:190
std::string * str_value
Definition: sexpr.h:193
_IN_STRING * sexpr_str
Definition: sexpr.h:194
union SEXPR::SEXPR_SCAN_ARG::@35 u
SEXPR_CHILDREN_ARG(const std::string &aValue)
Definition: sexpr.h:212