ZFFramework
Loading...
Searching...
No Matches
ZFEnumDeclare.h
Go to the documentation of this file.
1
5
6#ifndef _ZFI_ZFEnumDeclare_h_
7#define _ZFI_ZFEnumDeclare_h_
8
11
12// ============================================================
147#define ZFENUM_BEGIN(ZFLIB_, EnumName) \
148 _ZFP_ZFENUM_BEGIN(ZFLIB_, EnumName)
149
151#define ZFENUM_VALUE(Value) \
152 _ZFP_ZFENUM_VALUE(Value)
153
154#define ZFENUM_VALUE_WITH_INIT(Value, initValue) \
155 _ZFP_ZFENUM_VALUE_WITH_INIT(Value, initValue)
156
158#define ZFENUM_SEPARATOR() \
159 _ZFP_ZFENUM_SEPARATOR(zffalse)
160
161#define ZFENUM_SEPARATOR_ALLOW_DUPLICATE_VALUE() \
162 _ZFP_ZFENUM_SEPARATOR(zftrue)
163
165#define ZFENUM_VALUE_REGISTER_WITH_NAME(Value, Name) \
166 _ZFP_ZFENUM_VALUE_REGISTER_WITH_NAME(Value, Name)
167
168#define ZFENUM_VALUE_REGISTER(Value) \
169 _ZFP_ZFENUM_VALUE_REGISTER_WITH_NAME(Value, zftext(#Value))
170
172#define ZFENUM_END(ZFLIB_, EnumName) \
173 _ZFP_ZFENUM_END(ZFLIB_, EnumName)
174
175#define ZFENUM_END_WITH_DEFAULT(ZFLIB_, EnumName, defaultEnum) \
176 _ZFP_ZFENUM_END_WITH_DEFAULT(ZFLIB_, EnumName, defaultEnum)
177
179#define ZFENUM_END_FLAGS(ZFLIB_, EnumName, EnumFlagsName) \
180 _ZFP_ZFENUM_END_FLAGS(ZFLIB_, EnumName, EnumFlagsName)
181
182#define ZFENUM_END_FLAGS_WITH_DEFAULT(ZFLIB_, EnumName, EnumFlagsName, defaultEnum, defaultEnumFlags) \
183 _ZFP_ZFENUM_END_FLAGS_WITH_DEFAULT(ZFLIB_, EnumName, EnumFlagsName, defaultEnum, defaultEnumFlags)
184
186#define ZFENUM_REG(ZFLIB_, EnumName, ...) \
187 _ZFP_ZFENUM_TYPEID_REG(ZFLIB_, EnumName, __VA_ARGS__ ::)
188
189#define ZFENUM_REG_FLAGS(ZFLIB_, EnumName, EnumFlagsName, ...) \
190 ZFCORE_POD_DECLARE_NO_COMPARER(__VA_ARGS__ :: EnumFlagsName) \
191 _ZFP_ZFENUM_TYPEID_REG(ZFLIB_, EnumName, __VA_ARGS__ ::) \
192 _ZFP_ZFENUM_FLAGS_TYPEID_REG(ZFLIB_, EnumName, EnumFlagsName, __VA_ARGS__ ::)
193
195#define ZFENUM_DEFINE(EnumName) \
196 _ZFP_ZFENUM_DEFINE(EnumName)
197
199#define ZFENUM_DEFINE_FLAGS(EnumName, EnumFlagsName) \
200 _ZFP_ZFENUM_DEFINE_FLAGS(EnumName, EnumFlagsName)
201
202// ============================================================
203#define _ZFP_ZFENUM_BEGIN(ZFLIB_, EnumName) \
204 zfclass ZFLIB_ v_##EnumName : zfextend ZFEnum { \
205 ZFOBJECT_DECLARE(v_##EnumName, ZFEnum) \
206 public: \
207 \
208 typedef enum {
209
210#define _ZFP_ZFENUM_VALUE(Value) e_##Value,
211#define _ZFP_ZFENUM_VALUE_WITH_INIT(Value, initValue) e_##Value = initValue,
212
213#define _ZFP_ZFENUM_SEPARATOR(isEnableDuplicateValue_) \
214 \
215 ZFEnumCount, \
216 /* used to ensure sizeof(enum) == sizeof(zfuint) */ \
217 /* required for enum value reinterpret cast (ZFTAG_TRICKS: EnumReinterpretCast) */ \
218 _ZFP_ZFEnumMax = ((zfuint)-1), \
219 } ZFEnumType; \
220 public: \
221 \
222 static zfindex EnumCount(void) { \
223 return zfself::_ZFP_ZFEnumDataRef()->enumCount(); \
224 } \
225 \
226 static zfindex EnumIndexForValue(ZF_IN zfuint value) { \
227 return zfself::_ZFP_ZFEnumDataRef()->enumIndexForValue(value); \
228 } \
229 \
230 static zfuint EnumValueAt(ZF_IN zfindex index) { \
231 return zfself::_ZFP_ZFEnumDataRef()->enumValueAt(index); \
232 } \
233 \
234 static const zfstring &EnumNameAt(ZF_IN zfindex index) { \
235 return zfself::_ZFP_ZFEnumDataRef()->enumNameAt(index); \
236 } \
237 \
238 static zfbool EnumValueContain(ZF_IN zfuint value) { \
239 return zfself::_ZFP_ZFEnumDataRef()->enumValueContain(value); \
240 } \
241 \
242 static zfuint EnumValueForName(ZF_IN const zfstring &name) { \
243 return zfself::_ZFP_ZFEnumDataRef()->enumValueForName(name); \
244 } \
245 \
246 static const zfstring &EnumNameForValue(ZF_IN zfuint value) { \
247 return zfself::_ZFP_ZFEnumDataRef()->enumNameForValue(value); \
248 } \
249 public: \
250 \
251 zfoverride \
252 virtual zfindex enumCount(void) { \
253 return zfself::EnumCount(); \
254 } \
255 zfoverride \
256 virtual zfuint enumDefault(void) { \
257 return zfself::EnumDefault(); \
258 } \
259 zfoverride \
260 virtual zfbool enumIsFlags(void) { \
261 return zfself::EnumIsFlags(); \
262 } \
263 zfoverride \
264 virtual zfindex enumIndexForValue(ZF_IN zfuint value) { \
265 return zfself::EnumIndexForValue(value); \
266 } \
267 zfoverride \
268 virtual zfuint enumValueAt(ZF_IN zfindex index) { \
269 return zfself::EnumValueAt(index); \
270 } \
271 zfoverride \
272 virtual const zfstring &enumNameAt(ZF_IN zfindex index) { \
273 return zfself::EnumNameAt(index); \
274 } \
275 zfoverride \
276 virtual zfbool enumValueContain(ZF_IN zfuint value) { \
277 return zfself::EnumValueContain(value); \
278 } \
279 zfoverride \
280 virtual zfuint enumValueForName(ZF_IN const zfstring &name) { \
281 return zfself::EnumValueForName(name); \
282 } \
283 zfoverride \
284 virtual const zfstring &enumNameForValue(ZF_IN zfuint value) { \
285 return zfself::EnumNameForValue(value); \
286 } \
287 \
288 public: \
289 static const _ZFP_ZFEnumData *_ZFP_ZFEnumDataRef(void) { \
290 static _ZFP_ZFEnumDataHolder d(_ZFP_ZFEnumDataInit()); \
291 return d.d; \
292 } \
293 static const _ZFP_ZFEnumData *_ZFP_ZFEnumDataInit(void) { \
294 ZFCoreMutexLocker(); \
295 _ZFP_ZFEnumData *d = _ZFP_ZFEnumDataAccess(zfself::ClassData()); \
296 if(d->needInitFlag) { \
297 d->needInitFlag = zffalse; \
298 zfbool isEnableDuplicateValue = isEnableDuplicateValue_;
299
300#define _ZFP_ZFENUM_VALUE_REGISTER_WITH_NAME(Value, Name) \
301 d->add(isEnableDuplicateValue, zfself::e_##Value, Name);
302
303#define _ZFP_ZFENUM_END(ZFLIB_, EnumName) \
304 _ZFP_ZFENUM_END_DETAIL(ZFLIB_, EnumName, zffalse, d->enumValueAt(0))
305#define _ZFP_ZFENUM_END_WITH_DEFAULT(ZFLIB_, EnumName, defaultEnum) \
306 _ZFP_ZFENUM_END_DETAIL(ZFLIB_, EnumName, zffalse, zfself::e_##defaultEnum)
307
308#define _ZFP_ZFENUM_END_FLAGS(ZFLIB_, EnumName, EnumFlagsName) \
309 _ZFP_ZFENUM_END_DETAIL(ZFLIB_, EnumName, zftrue, d->enumValueAt(0)) \
310 _ZFP_ZFENUM_FLAGS_DECLARE(ZFLIB_, EnumName, EnumFlagsName, v_##EnumName::EnumDefault())
311#define _ZFP_ZFENUM_END_FLAGS_WITH_DEFAULT(ZFLIB_, EnumName, EnumFlagsName, defaultEnum, defaultEnumFlags) \
312 _ZFP_ZFENUM_END_DETAIL(ZFLIB_, EnumName, zftrue, zfself::e_##defaultEnum) \
313 _ZFP_ZFENUM_FLAGS_DECLARE(ZFLIB_, EnumName, EnumFlagsName, defaultEnumFlags)
314
315#define _ZFP_ZFENUM_END_DETAIL(ZFLIB_, EnumName, IsFlags, defaultEnum) \
316 d->enumDefault = (zfuint)(defaultEnum); \
317 d->enumIsFlags = (IsFlags); \
318 } \
319 return d; \
320 } \
321 public: \
322 \
323 static inline zfbool EnumIsFlags(void) { \
324 return (v_##EnumName::ZFEnumType)zfself::_ZFP_ZFEnumDataRef()->enumIsFlags; \
325 } \
326 \
327 static inline v_##EnumName::ZFEnumType EnumDefault(void) { \
328 return (v_##EnumName::ZFEnumType)zfself::_ZFP_ZFEnumDataRef()->enumDefault; \
329 } \
330 public: \
331 \
332 zffinal zfself::ZFEnumType zfv(void) { \
333 return (zfself::ZFEnumType)this->enumValue(); \
334 } \
335 public: \
336 zfoverride \
337 virtual const zfstring &zfvTypeId(void); \
338 }; \
339 \
340 typedef v_##EnumName::ZFEnumType EnumName; \
341 _ZFP_ZFENUM_CONVERTER_DECLARE(ZFLIB_, EnumName) \
342 _ZFP_ZFENUM_TYPEID_DECLARE(ZFLIB_, EnumName)
343
344// ============================================================
345#define _ZFP_ZFENUM_DEFINE(EnumName) \
346 _ZFP_ZFENUM_CONVERTER_DEFINE(EnumName) \
347 ZFOBJECT_REGISTER(v_##EnumName) \
348 _ZFP_ZFENUM_TYPEID_DEFINE(EnumName) \
349 ZF_STATIC_REGISTER_INIT(EnumReg_##EnumName) { \
350 for(zfindex i = 0; i < v_##EnumName::EnumCount(); ++i) { \
351 ZFMethodUserRegisterDetail_0(resultMethod, { \
352 return (EnumName)v_##EnumName::EnumValueForName(invokerMethod->methodName() + 2); \
353 }, v_##EnumName::ClassData(), public, ZFMethodTypeStatic \
354 , EnumName, zfstr("e_%s", v_##EnumName::EnumNameAt(i)) \
355 ); \
356 _m.add(resultMethod); \
357 } \
358 _ZFP_ZFEnumMethodReg(_m, v_##EnumName::_ZFP_ZFEnumDataRef()); \
359 } \
360 ZF_STATIC_REGISTER_DESTROY(EnumReg_##EnumName) { \
361 for(zfindex i = 0; i < _m.count(); ++i) { \
362 ZFMethodUserUnregister(_m[i]); \
363 } \
364 } \
365 ZFCoreArray<const ZFMethod *> _m; \
366 ZF_STATIC_REGISTER_END(EnumReg_##EnumName)
367
368#define _ZFP_ZFENUM_DEFINE_FLAGS(EnumName, EnumFlagsName) \
369 _ZFP_ZFENUM_DEFINE(EnumName) \
370 _ZFP_ZFENUM_FLAGS_DEFINE(EnumName, EnumFlagsName)
371
372// ============================================================
373#define _ZFP_ZFENUM_CONVERTER_DECLARE(ZFLIB_, EnumName) \
374 \
375 extern ZFLIB_ zfbool EnumName##FromStringT( \
376 ZF_OUT zfauto &ret \
377 , ZF_IN const zfchar *src \
378 , ZF_IN_OPT zfindex srcLen = zfindexMax() \
379 , ZF_OUT_OPT zfstring *errorHint = zfnull \
380 ); \
381 \
382 extern ZFLIB_ zfbool EnumName##ToStringT( \
383 ZF_IN_OUT zfstring &ret \
384 , ZF_IN v_##EnumName *const &value \
385 , ZF_OUT_OPT zfstring *errorHint = zfnull \
386 ); \
387 \
388 inline zfstring EnumName##ToString( \
389 ZF_IN v_##EnumName *const &value \
390 , ZF_OUT_OPT zfstring *errorHint = zfnull \
391 ) { \
392 zfstring ret; \
393 EnumName##ToStringT(ret, value, errorHint); \
394 return ret; \
395 }
396#define _ZFP_ZFENUM_CONVERTER_DEFINE(EnumName) \
397 zfbool EnumName##ToStringT( \
398 ZF_IN_OUT zfstring &ret \
399 , ZF_IN v_##EnumName *const &value \
400 , ZF_OUT_OPT zfstring *errorHint /* = zfnull */ \
401 ) { \
402 ret += ((value == zfnull) ? zfstring() : value->enumName()); \
403 return zftrue; \
404 } \
405 zfbool EnumName##FromStringT( \
406 ZF_OUT zfauto &ret \
407 , ZF_IN const zfchar *src \
408 , ZF_IN_OPT zfindex srcLen /* = zfindexMax() */ \
409 , ZF_OUT_OPT zfstring *errorHint /* = zfnull */ \
410 ) { \
411 if(zfstringIsEqual(src, srcLen, ZFEnumNameInvalid(), zfindexMax())) { \
412 ret = zfobj<v_##EnumName>(ZFEnumInvalid()); \
413 return zftrue; \
414 } \
415 zfuint tmpValue = v_##EnumName::EnumValueForName( \
416 (srcLen == zfindexMax()) ? src : zfstring(src, srcLen).cString()); \
417 if(tmpValue == ZFEnumInvalid()) { \
418 zfstringAppend(errorHint, "no enum named: \"%s\"", zfstring(src, srcLen)); \
419 return zffalse; \
420 } \
421 else { \
422 ret = zfobj<v_##EnumName>(tmpValue); \
423 return zftrue; \
424 } \
425 }
426
427// ============================================================
428#define _ZFP_ZFENUM_FLAGS_DECLARE(ZFLIB_, EnumName, EnumFlagsName, defaultValue) \
429 \
430 zffinal zfclassPOD ZFLIB_ EnumFlagsName { \
431 /* this class should be POD-like to support enum value reinterpret cast (ZFTAG_TRICKS: EnumReinterpretCast) */ \
432 public: \
433 \
434 static zfuint EnumDefault(void) { \
435 return defaultValue; \
436 } \
437 public: \
438 \
439 EnumFlagsName(void) : flags(0) {} \
440 EnumFlagsName(ZF_IN zfuint const &flags) : flags(flags) {} \
441 EnumFlagsName(ZF_IN EnumName const &flags) : flags((zfuint)flags) {} \
442 EnumFlagsName(ZF_IN EnumFlagsName const &ref) : flags(ref.flags) {} \
443 public: \
444 zfuint const &enumValue(void) const {return this->flags;} \
445 void enumValue(ZF_IN zfuint const &flags) {this->flags = flags;} \
446 void enumValue(ZF_IN EnumName const &flags) {this->flags = (zfuint)flags;} \
447 public: \
448 operator zfuint const & (void) const {return this->flags;} \
449 EnumFlagsName &operator = (ZF_IN zfuint const &flags) {this->flags = flags; return *this;} \
450 EnumFlagsName &operator = (ZF_IN EnumName const &flags) {this->flags = (zfuint)flags; return *this;} \
451 EnumFlagsName &operator = (ZF_IN EnumFlagsName const &ref) {this->flags = ref.flags; return *this;} \
452 zfbool operator == (ZF_IN zfuint const &flags) const {return (this->flags == flags);} \
453 zfbool operator == (ZF_IN EnumName const &flags) const {return (this->flags == (zfuint)flags);} \
454 zfbool operator == (ZF_IN EnumFlagsName const &ref) const {return (this->flags == ref.flags);} \
455 zfbool operator != (ZF_IN zfuint const &flags) const {return (this->flags != flags);} \
456 zfbool operator != (ZF_IN EnumName const &flags) const {return (this->flags != (zfuint)flags);} \
457 zfbool operator != (ZF_IN EnumFlagsName const &ref) const {return (this->flags != ref.flags);} \
458 EnumFlagsName &operator |= (ZF_IN zfuint const &flags) {this->flags |= flags; return *this;} \
459 EnumFlagsName &operator |= (ZF_IN EnumName const &flags) {this->flags |= (zfuint)flags; return *this;} \
460 EnumFlagsName &operator |= (ZF_IN EnumFlagsName const &ref) {this->flags |= ref.flags; return *this;} \
461 EnumFlagsName &operator &= (ZF_IN zfuint const &flags) {this->flags &= flags; return *this;} \
462 EnumFlagsName &operator &= (ZF_IN EnumName const &flags) {this->flags &= (zfuint)flags; return *this;} \
463 EnumFlagsName &operator &= (ZF_IN EnumFlagsName const &ref) {this->flags &= ref.flags; return *this;} \
464 public: \
465 void objectInfoT(ZF_IN_OUT zfstring &ret) const; \
466 inline zfstring objectInfo(void) const { \
467 zfstring ret; \
468 this->objectInfoT(ret); \
469 return ret; \
470 } \
471 \
472 private: \
473 zfuint flags; \
474 }; \
475 _ZFP_ZFENUM_FLAGS_TYPEID_DECLARE(ZFLIB_, EnumName, EnumFlagsName)
476
477#define _ZFP_ZFENUM_FLAGS_DEFINE(EnumName, EnumFlagsName) \
478 void EnumFlagsName::objectInfoT(ZF_IN_OUT zfstring &ret) const { \
479 zfflagsToStringT(ret, v_##EnumName::ClassData(), (zfflags)this->enumValue()); \
480 } \
481 _ZFP_ZFENUM_FLAGS_TYPEID_DEFINE(EnumName, EnumFlagsName)
482
483
484// ============================================================
485// normal enum
486#define _ZFP_ZFENUM_TYPEID_DECLARE(ZFLIB_, EnumName) \
487 ZFTYPEID_DECLARE_WITH_CUSTOM_WRAPPER(ZFLIB_, EnumName, EnumName)
488#define _ZFP_ZFENUM_TYPEID_REG(ZFLIB_, EnumName, Scope) \
489 \
490 template<> \
491 zfclassNotPOD ZFTypeId<Scope EnumName> : zfextend ZFTypeInfo { \
492 public: \
493 typedef Scope EnumName _ZFP_PropType; \
494 typedef Scope v_##EnumName _ZFP_WrapType; \
495 public: \
496 enum { \
497 TypeIdRegistered = 1, \
498 TypeIdSerializable = 1, \
499 }; \
500 static inline const zfstring &TypeId(void) { \
501 return Scope ZFTypeId_##EnumName(); \
502 } \
503 static inline const ZFClass *TypeIdClass(void) { \
504 return _ZFP_WrapType::ClassData(); \
505 } \
506 zfoverride \
507 virtual zfbool typeIdSerializable(void) const { \
508 return TypeIdSerializable; \
509 } \
510 zfoverride \
511 virtual const zfstring &typeId(void) const { \
512 return TypeId(); \
513 } \
514 zfoverride \
515 virtual const ZFClass *typeIdClass(void) const { \
516 return TypeIdClass(); \
517 } \
518 static zfbool ValueStore( \
519 ZF_OUT zfauto &obj \
520 , ZF_IN zfuint const &v \
521 ) { \
522 ZFCoreMutexLock(); \
523 _ZFP_WrapType *t = zfunsafe_zfobjAlloc(_ZFP_WrapType, v); \
524 obj.zfunsafe_assign(t); \
525 zfunsafe_zfobjRelease(t); \
526 ZFCoreMutexUnlock(); \
527 return zftrue; \
528 } \
529 static zfbool ValueStore( \
530 ZF_OUT zfauto &obj \
531 , ZF_IN _ZFP_PropType const &v \
532 ) { \
533 ZFCoreMutexLock(); \
534 _ZFP_WrapType *t = zfunsafe_zfobjAlloc(_ZFP_WrapType, (zfuint)v); \
535 obj.zfunsafe_assign(t); \
536 zfunsafe_zfobjRelease(t); \
537 ZFCoreMutexUnlock(); \
538 return zftrue; \
539 } \
540 template<typename T_Access = _ZFP_PropType \
541 , int T_Mode = ((zftTraits<typename zftTraits<T_Access>::TrNoRef>::TrIsPtr \
542 && !zftIsSame<typename zftTraits<T_Access>::TrNoRef, _ZFP_PropType>::Value) ? 1 \
543 : ((zftTraits<typename zftTraits<T_Access>::TrNoRef>::TrIsPtr \
544 && zftIsSame<typename zftTraits<T_Access>::TrNoRef, _ZFP_PropType>::Value \
545 && !zftTraits<T_Access>::TrIsRef) ? 2 : 0)) \
546 , typename T_Fix = void \
547 > \
548 zfclassNotPOD Value { \
549 public: \
550 static zfbool zfvAccessAvailable(ZF_IN const zfauto &obj) { \
551 return (zfcast(_ZFP_WrapType *, obj) != zfnull); \
552 } \
553 static T_Access zfvAccess(ZF_IN const zfauto &obj) { \
554 /* ZFTAG_TRICKS: EnumReinterpretCast */ \
555 return *(typename zftTraits<T_Access>::TrNoRef *)(&(zfcast(_ZFP_WrapType *, obj)->_ZFP_ZFEnum_value)); \
556 } \
557 static zfauto zfvAccessFinish(ZF_IN const zfauto &obj) { \
558 return zfnull; \
559 } \
560 }; \
561 template<typename T_Access> \
562 zfclassNotPOD Value<T_Access, 1> { \
563 public: \
564 static zfbool zfvAccessAvailable(ZF_IN const zfauto &obj) { \
565 return obj == zfnull || (zfcast(_ZFP_WrapType *, obj) != zfnull); \
566 } \
567 static typename zftTraits<T_Access>::TrNoRef zfvAccess(ZF_IN const zfauto &obj) { \
568 if(obj == zfnull) { \
569 return zfnull; \
570 } \
571 else { \
572 _ZFP_WrapType *t = zfcast(_ZFP_WrapType *, obj); \
573 /* ZFTAG_TRICKS: EnumReinterpretCast */ \
574 return (typename zftTraits<T_Access>::TrNoRef)(&(t->_ZFP_ZFEnum_value)); \
575 } \
576 } \
577 static zfauto zfvAccessFinish(ZF_IN const zfauto &obj) { \
578 return zfnull; \
579 } \
580 }; \
581 zfoverride \
582 virtual zfbool genericValueStore(ZF_OUT zfauto &obj, ZF_IN const void *v) const { \
583 return ValueStore(obj, *(const _ZFP_PropType *)v); \
584 } \
585 zfoverride \
586 virtual void *genericAccess(ZF_IN const zfauto &obj) const { \
587 if(!Value<_ZFP_PropType>::zfvAccessAvailable(obj)) { \
588 return zfnull; \
589 } \
590 else { \
591 return _ZFP_genericAccessWrap<_ZFP_PropType>(Value<_ZFP_PropType>::zfvAccess(obj)); \
592 } \
593 } \
594 zfoverride \
595 virtual zfauto genericAccessFinish(ZF_IN const zfauto &obj, ZF_IN void *v) const { \
596 return _ZFP_genericAccessFinishWrap(Value<_ZFP_PropType>::zfvAccessFinish(obj), v, _ZFP_genericAccessFinish<_ZFP_PropType>); \
597 } \
598 zfoverride \
599 virtual ZFCoreArrayBase *genericArrayNew(void) const { \
600 return ZFCoreArray<_ZFP_PropType>().refNew(); \
601 } \
602 }; \
603 \
604 ZFOUTPUT_TYPE(Scope EnumName, {s += Scope v_##EnumName::EnumNameForValue(v);})
605
606#define _ZFP_ZFENUM_TYPEID_DEFINE(EnumName) \
607 ZFTYPEID_DEFINE_BY_STRING_CONVERTER_WITH_CUSTOM_WRAPPER(EnumName, EnumName, { \
608 if(zfstringIsEqual(src, srcLen, ZFEnumNameInvalid(), zfindexMax())) { \
609 v = (EnumName)ZFEnumInvalid(); \
610 return zftrue; \
611 } \
612 v = (EnumName)v_##EnumName::EnumValueForName( \
613 (srcLen == zfindexMax()) ? src : zfstring(src, srcLen).cString() \
614 ); \
615 if(v == ZFEnumInvalid()) { \
616 if(errorHint) { \
617 zfstringAppend(errorHint, "invalid value: \"%s\"", zfstring(src, srcLen)); \
618 } \
619 return zffalse; \
620 } \
621 return zftrue; \
622 }, { \
623 s += v_##EnumName::EnumNameForValue(v); \
624 return zftrue; \
625 }) \
626 const zfstring &v_##EnumName::zfvTypeId(void) { \
627 return ZFTypeId_##EnumName(); \
628 }
629
630
631// ============================================================
632// enum flags
633#define _ZFP_ZFENUM_FLAGS_TYPEID_DECLARE(ZFLIB_, EnumName, EnumFlagsName) \
634 ZFTYPEID_DECLARE_WITH_CUSTOM_WRAPPER(ZFLIB_, EnumFlagsName, EnumFlagsName) \
635 \
636 typedef v_##EnumName v_##EnumFlagsName;
637#define _ZFP_ZFENUM_FLAGS_TYPEID_REG(ZFLIB_, EnumName, EnumFlagsName, Scope) \
638 \
639 template<> \
640 zfclassNotPOD ZFTypeId<Scope EnumFlagsName> : zfextend ZFTypeInfo { \
641 public: \
642 typedef Scope EnumName _ZFP_PropTypeOrig; \
643 typedef Scope EnumFlagsName _ZFP_PropType; \
644 typedef Scope v_##EnumFlagsName _ZFP_WrapType; \
645 public: \
646 enum { \
647 TypeIdRegistered = 1, \
648 TypeIdSerializable = 1, \
649 }; \
650 static inline const zfstring &TypeId(void) { \
651 return Scope ZFTypeId_##EnumFlagsName(); \
652 } \
653 static inline const ZFClass *TypeIdClass(void) { \
654 return _ZFP_WrapType::ClassData(); \
655 } \
656 zfoverride \
657 virtual zfbool typeIdSerializable(void) const { \
658 return TypeIdSerializable; \
659 } \
660 zfoverride \
661 virtual const zfstring &typeId(void) const { \
662 return TypeId(); \
663 } \
664 zfoverride \
665 virtual const ZFClass *typeIdClass(void) const { \
666 return TypeIdClass(); \
667 } \
668 static zfbool ValueStore( \
669 ZF_OUT zfauto &obj \
670 , ZF_IN zfuint const &v \
671 ) { \
672 ZFCoreMutexLock(); \
673 _ZFP_WrapType *t = zfunsafe_zfobjAlloc(_ZFP_WrapType, v); \
674 obj.zfunsafe_assign(t); \
675 zfunsafe_zfobjRelease(t); \
676 ZFCoreMutexUnlock(); \
677 return zftrue; \
678 } \
679 static zfbool ValueStore( \
680 ZF_OUT zfauto &obj \
681 , ZF_IN _ZFP_PropTypeOrig const &v \
682 ) { \
683 ZFCoreMutexLock(); \
684 _ZFP_WrapType *t = zfunsafe_zfobjAlloc(_ZFP_WrapType, (zfuint)v); \
685 obj.zfunsafe_assign(t); \
686 zfunsafe_zfobjRelease(t); \
687 ZFCoreMutexUnlock(); \
688 return zftrue; \
689 } \
690 static zfbool ValueStore( \
691 ZF_OUT zfauto &obj \
692 , ZF_IN _ZFP_PropType const &v \
693 ) { \
694 ZFCoreMutexLock(); \
695 _ZFP_WrapType *t = zfunsafe_zfobjAlloc(_ZFP_WrapType, (zfuint)v); \
696 obj.zfunsafe_assign(t); \
697 zfunsafe_zfobjRelease(t); \
698 ZFCoreMutexUnlock(); \
699 return zftrue; \
700 } \
701 template<typename T_Access = _ZFP_PropType \
702 , int T_Mode = ((zftTraits<typename zftTraits<T_Access>::TrNoRef>::TrIsPtr \
703 && !zftIsSame<typename zftTraits<T_Access>::TrNoRef, _ZFP_PropType>::Value) ? 1 \
704 : ((zftTraits<typename zftTraits<T_Access>::TrNoRef>::TrIsPtr \
705 && zftIsSame<typename zftTraits<T_Access>::TrNoRef, _ZFP_PropType>::Value \
706 && !zftTraits<T_Access>::TrIsRef) ? 2 : 0)) \
707 , typename T_Fix = void \
708 > \
709 zfclassNotPOD Value { \
710 public: \
711 static zfbool zfvAccessAvailable(ZF_IN const zfauto &obj) { \
712 return (zfcast(_ZFP_WrapType *, obj) != zfnull); \
713 } \
714 static T_Access zfvAccess(ZF_IN const zfauto &obj) { \
715 /* ZFTAG_TRICKS: EnumReinterpretCast */ \
716 return *(typename zftTraits<T_Access>::TrNoRef *)(&(zfcast(_ZFP_WrapType *, obj)->_ZFP_ZFEnum_value)); \
717 } \
718 static zfauto zfvAccessFinish(ZF_IN const zfauto &obj) { \
719 return zfnull; \
720 } \
721 }; \
722 template<typename T_Access> \
723 zfclassNotPOD Value<T_Access, 1> { \
724 public: \
725 static zfbool zfvAccessAvailable(ZF_IN const zfauto &obj) { \
726 return obj == zfnull || (zfcast(_ZFP_WrapType *, obj) != zfnull); \
727 } \
728 static typename zftTraits<T_Access>::TrNoRef zfvAccess(ZF_IN const zfauto &obj) { \
729 if(obj == zfnull) { \
730 return zfnull; \
731 } \
732 else { \
733 _ZFP_WrapType *t = zfcast(_ZFP_WrapType *, obj); \
734 /* ZFTAG_TRICKS: EnumReinterpretCast */ \
735 return (typename zftTraits<T_Access>::TrNoRef)(&(t->_ZFP_ZFEnum_value)); \
736 } \
737 } \
738 static zfauto zfvAccessFinish(ZF_IN const zfauto &obj) { \
739 return zfnull; \
740 } \
741 }; \
742 zfoverride \
743 virtual zfbool genericValueStore(ZF_OUT zfauto &obj, ZF_IN const void *v) const { \
744 return ValueStore(obj, *(const _ZFP_PropType *)v); \
745 } \
746 zfoverride \
747 virtual void *genericAccess(ZF_IN const zfauto &obj) const { \
748 if(!Value<_ZFP_PropType>::zfvAccessAvailable(obj)) { \
749 return zfnull; \
750 } \
751 else { \
752 return _ZFP_genericAccessWrap<_ZFP_PropType>(Value<_ZFP_PropType>::zfvAccess(obj)); \
753 } \
754 } \
755 zfoverride \
756 virtual zfauto genericAccessFinish(ZF_IN const zfauto &obj, ZF_IN void *v) const { \
757 return _ZFP_genericAccessFinishWrap(Value<_ZFP_PropType>::zfvAccessFinish(obj), v, _ZFP_genericAccessFinish<_ZFP_PropType>); \
758 } \
759 zfoverride \
760 virtual ZFCoreArrayBase *genericArrayNew(void) const { \
761 return ZFCoreArray<_ZFP_PropType>().refNew(); \
762 } \
763 }; \
764 \
765 ZFOUTPUT_TYPE(Scope EnumFlagsName, {v.objectInfoT(s);})
766
767#define _ZFP_ZFENUM_FLAGS_TYPEID_DEFINE(EnumName, EnumFlagsName) \
768 ZFTYPEID_DEFINE_BY_STRING_CONVERTER_WITH_CUSTOM_WRAPPER(EnumFlagsName, EnumFlagsName, { \
769 zfflags flags = 0; \
770 if(!zfflagsFromStringT(flags, \
771 v_##EnumName::ClassData(), \
772 src, srcLen)) { \
773 if(errorHint) { \
774 zfstringAppend(errorHint, "invalid value: \"%s\"", zfstring(src, srcLen)); \
775 } \
776 return zffalse; \
777 } \
778 v.enumValue((zfuint)flags); \
779 return zftrue; \
780 }, { \
781 return zfflagsToStringT(s, v_##EnumName::ClassData(), (zfflags)v.enumValue()); \
782 }) \
783 ZF_STATIC_REGISTER_INIT(EnumReg_##EnumFlagsName) { \
784 ZFClassAlias(v_##EnumName::ClassData(), v_##EnumName::ClassData()->classNamespace() \
785 ? zfstr("%s.%s", v_##EnumName::ClassData()->classNamespace(), #EnumFlagsName).cString() \
786 : #EnumFlagsName \
787 ); \
788 } \
789 ZF_STATIC_REGISTER_DESTROY(EnumReg_##EnumFlagsName) { \
790 ZFClassAliasRemove(v_##EnumName::ClassData(), v_##EnumName::ClassData()->classNamespace() \
791 ? zfstr("%s.%s", v_##EnumName::ClassData()->classNamespace(), #EnumFlagsName).cString() \
792 : #EnumFlagsName \
793 ); \
794 } \
795 ZF_STATIC_REGISTER_END(EnumReg_##EnumFlagsName)
796
798#endif // #ifndef _ZFI_ZFEnumDeclare_h_
799
#define ZF_NAMESPACE_GLOBAL_BEGIN
begin namespace ZFFramework
Definition ZFNamespace.h:97
#define ZF_NAMESPACE_GLOBAL_END
end namespace ZFFramework
Definition ZFNamespace.h:98
types for ZFFramework