AuROXTL/Include/auROXTL/Objects/ClassHelpers.hpp
2022-04-01 05:06:53 +01:00

131 lines
4.8 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Objects.hpp
File: AuroraMacros.hpp
File: AU_MACROS.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
/*
AU_DEFINE_FOR_VA(Object,
(AU_DEFINE_CTOR_VA, // initializer-list-like ctor (extending a struct or adding a ctor will break initializer lists)
AU_DEFINE_THIS_MOVE_CTOR_VA, // add move `Object(Object &&)`
AU_DEFINE_EQUALS_VA, // add equals operator
AU_DEFINE_MOVE_VA, // add move assignment operator
AU_DEFINE_COPY_VA), // add copy assignment operator
(id, task));
*/
/// @hideinitializer
#define AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(variable) AuRemoveConst_t<AuRemoveReference_t<decltype(variable)>>
/// @hideinitializer
#define AU_EMIT_CTOR_CPY(pair) const AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(pair) &pair
/// @hideinitializer
#define AU_EMIT_CTOR_CPY_SECOND(pair) ,AU_EMIT_CTOR_CPY(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_MOV(pair) AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(pair) &&pair
/// @hideinitializer
#define AU_EMIT_CTOR_MOV_SECOND(pair) ,AU_EMIT_CTOR_MOV(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN(pair) pair(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN_SECOND(pair) ,AU_EMIT_CTOR_ASSIGN(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN2(pair) pair(cpy.pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN2_SECOND(pair) ,AU_EMIT_CTOR_ASSIGN2(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_MOVE_ASSIGN2(pair) pair(AuMove(cpy.pair))
/// @hideinitializer
#define AU_EMIT_CTOR_MOVE_ASSIGN2_SECOND(pair) ,AU_EMIT_CTOR_MOVE_ASSIGN2(pair)
/// @hideinitializer
#define AU_DEFINE_CTOR_VA_(thisType, args) AU_DEFINE_CTOR_CPY_VA(thisType, args) AU_DEFINE_CTOR_MOV_VA(thisType, args)
/// @deprecated
#define AU_DEFINE_CTOR_ONE(thisType, pairTypeName) AU_DEFINE_CTOR_VA_(thisType, (AU_EMIT_SECOND pairTypeName))
/// @hideinitializer
#define AU_DEFINE_EQUALS_VA_A(name) this->name == ref.name
/// @hideinitializer
#define AU_DEFINE_EQUALS_VA_B(name) && AU_DEFINE_EQUALS_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_EQUALS_HASHCODE_A(name) AuHashCode(this->name)
/// @hideinitializer
#define AU_DEFINE_EQUALS_HASHCODE_B(name) ^ AU_DEFINE_EQUALS_HASHCODE_A(name)
/// @hideinitializer
#define AU_DEFINE_MOVE_VA_A(name) this->name = AuMove(ref.name);
/// @hideinitializer
#define AU_DEFINE_MOVE_VA_B(name) AU_DEFINE_MOVE_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_COPY_VA_A(name) this->name = ref.name;
/// @hideinitializer
#define AU_DEFINE_COPY_VA_B(name) AU_DEFINE_COPY_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_CTOR_CPY_VA(thisType, args) \
inline thisType(AU_FOR_EACH_FIRST(AU_EMIT_CTOR_CPY, AU_EMIT_CTOR_CPY_SECOND, AU_STRIP_BRACKETS(args))) : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN, AU_EMIT_CTOR_ASSIGN_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_CTOR_MOV_VA(thisType, args) \
inline thisType(AU_FOR_EACH_FIRST(AU_EMIT_CTOR_MOV, AU_EMIT_CTOR_MOV_SECOND, AU_STRIP_BRACKETS(args))) noexcept : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN, AU_EMIT_CTOR_ASSIGN_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_THIS_COPY_CTOR_VA(thisType, args) \
inline thisType(const thisType &cpy) : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN2, AU_EMIT_CTOR_ASSIGN2_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_THIS_MOVE_CTOR_VA(thisType, args) \
inline thisType(thisType &&cpy) noexcept : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_MOVE_ASSIGN2, AU_EMIT_CTOR_MOVE_ASSIGN2_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_FOR_VA_(pair, func) func(AU_EMIT_SECOND pair, AU_STRIP_BRACKETS(AU_EMIT_FIRST pair))
///
#define AU_DEFINE_HASHCODE_VA(thisType, args) AuUInt HashCode() const noexcept { return AU_FOR_EACH_FIRST(AU_DEFINE_EQUALS_HASHCODE_A, AU_DEFINE_EQUALS_HASHCODE_B, AU_STRIP_BRACKETS(args)) ; }
///
#define AU_DEFINE_CTOR_VA(thisType, args) AU_DEFINE_CTOR_CPY_VA(thisType, args) AU_DEFINE_CTOR_MOV_VA(thisType, args)
///
#define AU_DEFINE_EQUALS_VA(thisType, args) bool operator==(const thisType & ref) const noexcept { return AU_FOR_EACH_FIRST(AU_DEFINE_EQUALS_VA_A, AU_DEFINE_EQUALS_VA_B, AU_STRIP_BRACKETS(args)) ; }
///
#define AU_DEFINE_MOVE_VA(thisType, args) thisType& operator=( thisType && ref) noexcept { AU_FOR_EACH_FIRST(AU_DEFINE_MOVE_VA_A, AU_DEFINE_MOVE_VA_B, AU_STRIP_BRACKETS(args)) return *this; }
///
#define AU_DEFINE_COPY_VA(thisType, args) thisType& operator=(const thisType & ref) { AU_FOR_EACH_FIRST(AU_DEFINE_COPY_VA_A, AU_DEFINE_COPY_VA_B, AU_STRIP_BRACKETS(args)) return *this; }
//
#define AU_DEFINE_FOR_VA(type, arry, members) AU_FOR_EACH_THAT(AU_DEFINE_FOR_VA_, ((members), type), AU_STRIP_BRACKETS(arry))