8 #define partition algorithm_partition
26 #define YAML_PTR_FIELD(sd, class, name, type) do { \
27 assert(typeid(&class::name) == typeid(type *class::*)); \
28 sd.m[ #name ] = new ptr_field((ptr_field_t) &class::name, &typeid(type)); \
30 #define YAML_INT_FIELD(sd, class, name) \
31 sd.m[ #name ] = new int_field(static_cast<int_field_t>(&class::name), &typeid(int));
32 #define YAML_ENUM_FIELD(sd, class, name, names) \
33 sd.m[ #name ] = new_enum_field(&class::name, \
34 names, sizeof(names)/sizeof(*names));
35 #define YAML_SEQ_FIELD(sd, class, name, type) \
36 sd.m[ #name ] = new seq_field<type> \
37 ((seq_field<type>::seq_field_t) &class::name);
43 at_init(void (*f
)(void)) { f(); }
48 typedef serialize
* serialize_p
;
51 serialize
*(*create
)(void *user
);
52 serialize_p (*convert
) (anchor_map
*, serialize
*, const type_info
*);
53 const type_info
*type
;
58 template <class el
> struct seq_field
;
62 friend bool operator==(const replacer_base
& a
, const replacer_base
& b
);
65 replacer_base(serialize
*& r
) : ref(r
) {}
66 virtual void with(serialize
*replacement
) {
71 inline bool operator==(const replacer_base
& a
, const replacer_base
& b
)
73 return &a
.ref
== &b
.ref
;
77 class replacer
: public replacer_base
{
79 replacer(el
*& r
) : replacer_base((serialize
*&)r
) {}
80 virtual void with(serialize
*replacement
) {
81 ref
= dynamic_cast<el
*>(replacement
);
85 typedef map
<serialize
*, unsigned> refset
;
90 map
<serialize
*, SYMID
> anchors
;
91 emitter() { e
= yll_new_emitter(); }
92 ~emitter() { yll_free_emitter(e
); }
93 bool anchor_handled(serialize
*s
);
96 struct description_map
{
97 map
<string
, description
*> *desc
;
109 static void syck_output_handler(YllEmitter
*p
, char *s
, long len
);
110 static SYMID
syck_handler(SyckParser
*p
, SyckNode
*n
);
111 static SyckNode
* bad_anchor_handler(SyckParser
*, char *);
114 friend struct ptr_field
;
115 friend struct int_field
;
116 template <class el
> friend struct seq_field
;
118 static map
<string
, description
*>& s_desc() {
119 static description_map desc
;
121 desc
.desc
= new map
<string
, description
*>;
124 static map
<const type_info
*, description
*>& t_desc() {
125 static map
<const type_info
*, description
*> *desc
= 0;
127 desc
= new map
<const type_info
*, description
*>;
131 static void register_type(const char *, const type_info
*, description
*);
134 static serialize
*Load(SyckParser
*parser
, const type_info
*type
,
136 static serialize
*Load(char *str
, const type_info
*type
, void *user
);
137 static serialize
*Load(FILE *fp
, const type_info
*type
, void *user
);
139 void Dump(FILE *out
= stdout
);
140 virtual void Dump(emitter
& e
) {
141 if (!e
.anchor_handled(this))
144 virtual void dump(emitter
& e
) = 0;
146 virtual void collect_references(refset
& refs
);
150 virtual void init(SyckParser
*p
, SyckNode
*n
) = 0;
152 virtual ~serialize() {
157 typedef pair
<SYMID
, std::vector
<replacer_base
*> > rep_pair
;
160 map
<serialize
*, rep_pair
> anchors
;
166 void add(serialize
* s
, SYMID id
) {
167 anchors
[s
] = rep_pair(id
, std::vector
<replacer_base
*>());
169 void replace(serialize
*s
, replacer_base
*orig
, replacer_base
*replace
) {
171 for (int i
= 0; i
< anchors
[s
].second
.size(); ++i
) {
172 replacer_base
* r
= anchors
[s
].second
[i
];
175 anchors
[s
].second
[i
] = replace
;
181 this->replace(s
, replace
);
183 void replace(serialize
*s
, replacer_base
*replace
) {
184 anchors
[s
].second
.push_back(replace
);
186 bool is_anchor(serialize
*s
) { return anchors
.find(s
) != anchors
.end(); }
187 serialize
* replace(SYMID id
, serialize
*replacement
);
188 serialize
* replace(serialize
* orig
, serialize
*replacement
) {
189 return replace(anchors
[orig
].first
, replacement
);
192 anchor_map(SyckParser
*_p
, void *user
) : p(_p
), user(user
) {}
195 class bad_anchor
: public serialize
{
197 void init(SyckParser
*p
, SyckNode
*n
) {};
198 void dump(emitter
& e
) { assert(0); }
201 class str
: public serialize
{
205 str(string _s
) : s(_s
) {}
206 static void register_type();
207 static serialize
*create(void *user
);
208 void init(SyckParser
*p
, SyckNode
*n
);
209 void dump(emitter
& e
) { yll_emitter_write_string(e
.e
, s
.c_str()); }
212 class integer
: public serialize
{
213 static serialize_p
convert (anchor_map
*, serialize
*, const type_info
*);
218 integer(int _v
) : v(_v
) {}
219 static void register_type();
220 static serialize
*create(void *user
);
221 void init(SyckParser
*p
, SyckNode
*n
);
222 void dump(emitter
& e
) { yll_emitter_write_int(e
.e
, v
); }
225 typedef map
<string
, serialize
*> sermap
;
227 typedef map
<string
,serialize_p
>::mapped_type mapped_type
;
229 class dict
: public serialize
{
233 map
<string
,serialize_p
> *d
;
235 //static void register_type();
236 static serialize_p
create();
237 void init(SyckParser
*p
, SyckNode
*n
);
238 void dump(emitter
& e
);
240 void collect_references(refset
& refs
);
242 mapped_type
& operator[](string s
) { return (*d
)[s
]; }
251 class seq
: public serialize
{
255 //static void register_type();
256 static serialize_p
create() { return new seq
<el
>; }
258 void init(SyckParser
*p
, SyckNode
*n
) {
259 anchor_map
*anchors
= (anchor_map
*) p
->bonus
;
260 for (int i
= 0; i
< n
->data
.list
->idx
; i
++) {
262 SYMID oid
= syck_seq_read(n
, i
);
263 syck_lookup_sym( p
, oid
, (char **)&val
);
266 // In a second iteration, since we wouldn't want the
267 // memory locations to change for the replacer
268 for (int i
= 0; i
< n
->data
.list
->idx
; i
++) {
269 if (anchors
->is_anchor(v
[i
])) {
270 anchors
->replace(v
[i
], new replacer
<el
>(v
[i
]));
275 void collect_references(refset
& refs
) {
276 serialize::collect_references(refs
);
277 for (int i
= 0; i
< v
.size(); ++i
) {
279 if (refs
.find(e
) == refs
.end())
280 e
->collect_references(refs
);
286 void dump(emitter
& e
) {
287 yll_emitter_start_seq(e
.e
);
288 for (int i
= 0; i
< v
.size(); ++i
) {
291 yll_emitter_end_seq(e
.e
);
294 el
*& operator[](int i
) { return v
[i
]; }
295 el
* const & operator[](int i
) const { return v
[i
]; }
296 size_t size() const { return v
.size(); }
297 void push_back(el
*e
) { v
.push_back(e
); }
298 void resize(int n
) { v
.resize(n
); }
299 void erase(el
*e
) { if (find(v
.begin(), v
.end(), e
) != v
.end())
300 v
.erase(find(v
.begin(), v
.end(), e
)); }
307 class seq
<int> : public serialize
{
311 //static void register_type();
312 static serialize_p
create() { return new seq
<int>; }
314 void init(SyckParser
*p
, SyckNode
*n
) {
315 for (int i
= 0; i
< n
->data
.list
->idx
; i
++) {
317 SYMID oid
= syck_seq_read(n
, i
);
318 syck_lookup_sym( p
, oid
, (char **)&val
);
319 v
.push_back(atoi(val
->s
.c_str()));
323 void collect_references(refset
& refs
) {
324 serialize::collect_references(refs
);
327 void dump(emitter
& e
) { assert(0); }
329 int& operator[](int i
) { return v
[i
]; }
330 int const & operator[](int i
) const { return v
[i
]; }
331 size_t size() const { return v
.size(); }
332 void push_back(int e
) { v
.push_back(e
); }
333 void resize(int n
) { v
.resize(n
); }
340 typedef serialize
* structure::* ptr_field_t
;
341 typedef int structure::* int_field_t
;
344 const type_info
*type
;
346 field(const type_info
*t
) : type(t
) {};
347 virtual bool set(anchor_map
*am
, structure
*, serialize
*&) { assert(0); }
348 virtual void collect(structure
* s
, refset
& refs
) { assert(0); }
349 virtual void dump(structure
* s
, emitter
& refs
) { assert(0); }
350 virtual bool is_empty(structure
*) { return false; }
353 struct ptr_field
: field
{
354 serialize
* structure::* pos
;
355 ptr_field(ptr_field_t p
, const type_info
*t
) : pos(p
), field(t
) {};
356 bool set(anchor_map
*am
, structure
*, serialize
*&);
357 void collect(structure
* s
, refset
& refs
);
358 void dump(structure
* s
, emitter
& refs
);
359 bool is_empty(structure
* s
) { return !(s
->*pos
); }
362 struct int_field
: field
{
363 int structure::* pos
;
364 int_field(int_field_t p
, const type_info
*t
) : pos(p
), field(t
) {};
365 bool set(anchor_map
*am
, structure
*, serialize
*&);
366 void collect(structure
* s
, refset
& refs
);
367 void dump(structure
* s
, emitter
& refs
);
370 template <typename T
, class C
>
371 struct enum_field
: field
{
375 enum_field(T
C::* p
, const char **names
,
376 const int size
) : names(names
), size(size
), pos(p
), field(&typeid(T
)) {};
377 bool set(anchor_map
*am
, structure
*, serialize
*&);
378 void collect(structure
* s
, refset
& refs
) { }
379 void dump(structure
* s
, emitter
& refs
);
382 template <typename T
, class C
>
383 bool enum_field
<T
,C
>::set(anchor_map
*am
, structure
* sc
, serialize
*& el
)
385 str
*s
= dynamic_cast<str
*>(el
);
386 C
*c
= dynamic_cast<C
*>(sc
);
390 if (!strcmp(s
->s
.c_str(), "~")) {
391 c
->*pos
= static_cast<T
>(-1);
396 for (int i
= 0; i
< size
; ++i
)
397 if (!strcmp(s
->s
.c_str(), names
[i
])) {
398 c
->*pos
= static_cast<T
>(i
);
406 template <typename T
, class C
>
407 void enum_field
<T
,C
>::dump(structure
* sc
, emitter
& e
)
409 C
*c
= dynamic_cast<C
*>(sc
);
410 if (c
->*pos
>= 0 && c
->*pos
< size
)
411 yll_emitter_write_string(e
.e
, names
[c
->*pos
]);
413 yll_emitter_write_null(e
.e
);
416 template <typename T
, class C
>
417 inline field
*new_enum_field(T
C::* p
, const char **names
, const int size
)
419 return new enum_field
<T
,C
>(p
, names
, size
);
423 struct seq_field
: field
{
424 typedef seq
<el
> structure::* seq_field_t
;
426 seq
<el
> structure::* pos
;
427 seq_field(seq_field_t p
) : pos(p
), field(&typeid(el
)) {};
428 bool set(anchor_map
*am
, structure
* c
, serialize
* &s
) {
429 map
<const type_info
*, description
*>& desc
= serialize::t_desc();
430 seq
<serialize
> * sq
= dynamic_cast<seq
<serialize
>*>(s
);
433 (c
->*pos
).v
= std::vector
<el
*>(sq
->size());
434 for (int i
= 0; i
< sq
->size(); ++i
) {
435 serialize
* e
= sq
->v
[i
];
436 if (typeid(el
) != typeid(*e
))
437 e
= desc
[&typeid(el
)]->convert(am
, e
, type
);
439 (c
->*pos
).v
[i
] = dynamic_cast<el
*>(e
);
441 if (am
->is_anchor(e
)) {
442 am
->replace(e
, new replacer
<serialize
>(sq
->v
[i
]),
443 new replacer
<el
>((c
->*pos
).v
[i
]));
449 void collect(structure
* c
, refset
& refs
) {
450 std::vector
<el
*> & v
= (c
->*pos
).v
;
451 for (int i
= 0; i
< v
.size(); ++i
) {
455 if (refs
.find(e
) == refs
.end())
456 e
->collect_references(refs
);
461 void dump(structure
* s
, emitter
& emit
) {
462 std::vector
<el
*> & v
= (s
->*pos
).v
;
463 yll_emitter_start_seq(emit
.e
);
464 for (int i
= 0; i
< v
.size(); ++i
) {
469 yll_emitter_write_null(emit
.e
);
471 yll_emitter_end_seq(emit
.e
);
473 bool is_empty(structure
* s
) { return (s
->*pos
).v
.size() == 0; }
477 struct seq_field
<int> : field
{
478 typedef seq
<int> structure::* seq_field_t
;
480 seq
<int> structure::* pos
;
481 seq_field(seq_field_t p
) : pos(p
), field(&typeid(int)) {};
482 bool set(anchor_map
*am
, structure
* c
, serialize
* &s
) {
483 map
<const type_info
*, description
*>& desc
= serialize::t_desc();
484 seq
<serialize
> * sq
= dynamic_cast<seq
<serialize
>*>(s
);
487 (c
->*pos
).v
= std::vector
<int>(sq
->size());
488 for (int i
= 0; i
< sq
->size(); ++i
) {
489 serialize
* e
= sq
->v
[i
];
490 if (typeid(str
) != typeid(*e
))
491 e
= desc
[&typeid(str
)]->convert(am
, e
, type
);
492 str
* s
= dynamic_cast<str
*>(e
);
494 (c
->*pos
).v
[i
] = atoi(s
->s
.c_str());
500 void collect(structure
* c
, refset
& refs
) {
502 void dump(structure
* s
, emitter
& emit
) {
503 std::vector
<int> & v
= (s
->*pos
).v
;
504 yll_emitter_set_options(emit
.e
, YLL_INLINE_SEQ
);
505 yll_emitter_start_seq(emit
.e
);
506 for (int i
= 0; i
< v
.size(); ++i
) {
507 yll_emitter_write_int(emit
.e
, v
[i
]);
509 yll_emitter_end_seq(emit
.e
);
513 typedef map
<string
, field
*> fieldmap
;
515 struct struct_description
{
518 ~struct_description() {
519 fieldmap::iterator j
;
520 for (j
= m
.begin(); j
!= m
.end(); ++j
)
525 class structure
: public serialize
{
528 map
<string
,serialize_p
> *d
;
530 static void register_type(const char *, const type_info
*, description
*);
531 static serialize_p
convert (anchor_map
*, serialize
*, const type_info
*);
533 void collect_references(refset
& refs
);
534 void init(SyckParser
*p
, SyckNode
*n
);
535 void dump(emitter
& e
);
536 virtual void fill_fields(anchor_map
*);
538 structure() { d
= NULL
; }
539 ~structure() { if (d
) delete d
; }
542 serialize
*Load(char *str
, const type_info
*type
= NULL
, void *user
= NULL
);
543 serialize
*Load(FILE *fp
, const type_info
*type
= NULL
, void *user
= NULL
);
545 T
*Load(char *str
, void *user
= NULL
) {
546 return dynamic_cast<T
*>(Load(str
, &typeid(T
), user
));
549 T
*Load(FILE *fp
, void *user
= NULL
) {
550 return dynamic_cast<T
*>(Load(fp
, &typeid(T
), user
));