#ifndef CHILON_GETSET_HPP
#define CHILON_GETSET_HPP
#include <chilon/attribute.hpp>
/// Set CHILON_GET_PREFIX to change the prefix of getter methods.
/// Set CHILON_GET_CONST_PREFIX to change the prefix of const getter methods,
/// it defaults to CHILON_GET_PREFIX.
/// Set CHILON_SET_PREFIX to change the prefix of setter methods
#define CHILON_CONCAT_HELPER(arg1,arg2) arg1##arg2
#define CHILON_CONCAT(arg1,arg2) CHILON_CONCAT_HELPER(arg1,arg2)
#ifdef CHILON_GET_PREFIX
# define CHILON_GET_PREFIX_HELPER(attribute) \
CHILON_CONCAT(CHILON_GET_PREFIX,attribute)
# ifndef CHILON_GET_CONST_PREFIX
# define CHILON_GET_CONST_PREFIX CHILON_GET_PREFIX
# endif
#else
# define CHILON_GET_PREFIX_HELPER(attribute) attribute
#endif
#ifdef CHILON_GET_CONST_PREFIX
# define CHILON_GET_CONST_PREFIX_HELPER(attribute) \
CHILON_CONCAT(CHILON_GET_CONST_PREFIX,attribute)
#else
# define CHILON_GET_CONST_PREFIX_HELPER(attribute) attribute
#endif
#ifdef CHILON_SET_PREFIX
# define CHILON_SET_PREFIX_HELPER(attribute) \
CHILON_CONCAT(CHILON_SET_PREFIX,attribute)
#else
# define CHILON_SET_PREFIX_HELPER(attribute) attribute
#endif
/// Declare an accessor that returns a const reference.
#define CHILON_GET_HELPER(attribute, var_suffix, suffix) \
decltype(CHILON_ATTRIBUTE(attribute)) var_suffix CHILON_GET_CONST_PREFIX_HELPER(attribute)() suffix { return CHILON_ATTRIBUTE(attribute); }
/// Accesor that returns whatever type the variable is
#define CHILON_GET(attribute) \
CHILON_GET_HELPER(attribute, , )
/// Accesor that returns whatever type the variable is but make it constant
#define CHILON_GET_CONST(attribute) \
CHILON_GET_HELPER(attribute, const, const)
/// Accesors for the attribute, const and mutable
#define CHILON_GET_MUTABLE(attribute) \
CHILON_GET(attribute) \
CHILON_GET_CONST(attribute)
/// Accessor that returns a reference to whatever type the attribute is.
#define CHILON_GET_REF(attribute) \
CHILON_GET_HELPER(attribute, &, )
/// Accessor that returns a const reference.
#define CHILON_GET_REF_CONST(attribute) \
CHILON_GET_HELPER(attribute, const&, const)
/// Accesors that return mutable and const references.
#define CHILON_GET_REF_MUTABLE(attribute) \
CHILON_GET_REF(attribute) \
CHILON_GET_REF_CONST(attribute)
#define CHILON_SET_HELPER(attribute) \
void CHILON_SET_PREFIX_HELPER(attribute)(decltype(CHILON_ATTRIBUTE(attribute)) const& ___attribute) { \
CHILON_ATTRIBUTE(attribute) = ___attribute; }
/// Accessor as for CHILON_GET and add a setter
#define CHILON_GETSET(attribute) \
CHILON_GET(attribute) \
CHILON_SET_HELPER(attribute)
/// Accessor as for CHILON_GET_CONST and add a setter
#define CHILON_GETSET_CONST(attribute) \
CHILON_GET_CONST(attribute) \
CHILON_SET_HELPER(attribute)
/// Accessors as for CHILON_GET_MUTABLE and add a setter
#define CHILON_GETSET_MUTABLE(attribute) \
CHILON_GET_MUTABLE(attribute) \
CHILON_SET_HELPER(attribute)
/// Accessor as for CHILON_GET_REF and add a setter
#define CHILON_GETSET_REF(attribute) \
CHILON_GET_REF(attribute) \
CHILON_SET_HELPER(attribute)
/// Accessor as for CHILON_GET_REF_CONST and add a setter
#define CHILON_GETSET_REF_CONST(attribute) \
CHILON_GET_REF_CONST(attribute) \
CHILON_SET_HELPER(attribute)
/// Accessors as for CHILON_GET_REF_MUTABLE and add a setter
#define CHILON_GETSET_REF_MUTABLE(attribute) \
CHILON_GET_REF_MUTABLE(attribute) \
CHILON_SET_HELPER(attribute)
#endif