| #pragma once |
| |
| #ifndef TCG_AUTO_H |
| #define TCG_AUTO_H |
| |
| #include "base.h" |
| #include "traits.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| namespace tcg |
| { |
| |
| |
| |
| |
| |
| struct _auto_type { |
| mutable bool m_destruct; |
| |
| public: |
| _auto_type(bool destruct) : m_destruct(destruct) {} |
| _auto_type(const _auto_type &other) : m_destruct(other.m_destruct) |
| { |
| other.m_destruct = false; |
| } |
| _auto_type &operator=(const _auto_type &other) |
| { |
| m_destruct = other.m_destruct, other.m_destruct = false; |
| return *this; |
| } |
| }; |
| |
| typedef const _auto_type &auto_type; |
| |
| |
| |
| |
| |
| template <typename Op> |
| struct auto_zerary : public _auto_type { |
| Op m_op; |
| |
| public: |
| auto_zerary(bool destruct = true) : _auto_type(destruct) {} |
| ~auto_zerary() |
| { |
| if (this->m_destruct) |
| m_op(); |
| } |
| }; |
| |
| |
| |
| template <typename Op, typename T = typename function_traits<Op>::arg1_type> |
| struct auto_unary : public _auto_type { |
| T m_arg1; |
| Op m_op; |
| |
| public: |
| auto_unary(bool destruct = true) : _auto_type(destruct) {} |
| auto_unary(Op op, T arg, bool destruct = true) |
| : _auto_type(destruct), m_arg1(arg), m_op(op) {} |
| ~auto_unary() |
| { |
| if (this->m_destruct) |
| m_op(m_arg1); |
| } |
| }; |
| |
| |
| |
| template <typename Op, typename T1 = typename function_traits<Op>::arg1_type, |
| typename T2 = typename function_traits<Op>::arg2_type> |
| struct auto_binary : public _auto_type { |
| T1 m_arg1; |
| T2 m_arg2; |
| Op m_op; |
| |
| public: |
| auto_binary(bool destruct = true) : _auto_type(destruct) {} |
| auto_binary(Op op, T1 arg1, T2 arg2, bool destruct = true) |
| : _auto_type(destruct), m_arg1(arg1), m_arg2(arg2), m_op(op) {} |
| ~auto_binary() |
| { |
| if (this->m_destruct) |
| m_op(m_arg1, m_arg2); |
| } |
| }; |
| |
| |
| |
| |
| |
| template <typename Op> |
| auto_zerary<Op> make_auto(Op op, bool destruct = true) |
| { |
| return auto_zerary<Op>(op, destruct); |
| } |
| |
| template <typename Op, typename T> |
| auto_unary<Op> make_auto(Op op, T &arg1, bool destruct = true) |
| { |
| return auto_unary<Op>(op, arg1, destruct); |
| } |
| |
| template <typename Op, typename T> |
| auto_unary<Op> make_auto(Op op, const T &arg1, bool destruct = true) |
| { |
| return auto_unary<Op>(op, arg1, destruct); |
| } |
| |
| template <typename Op, typename T1, typename T2> |
| auto_binary<Op> make_auto(Op op, T1 &arg1, T2 &arg2, bool destruct = true) |
| { |
| return auto_binary<Op>(op, arg1, arg2, destruct); |
| } |
| |
| template <typename Op, typename T1, typename T2> |
| auto_binary<Op> make_auto(Op op, const T1 &arg1, T2 &arg2, bool destruct = true) |
| { |
| return auto_binary<Op>(op, arg1, arg2, destruct); |
| } |
| |
| template <typename Op, typename T1, typename T2> |
| auto_binary<Op> make_auto(Op op, T1 &arg1, const T2 &arg2, bool destruct = true) |
| { |
| return auto_binary<Op>(op, arg1, arg2, destruct); |
| } |
| |
| template <typename Op, typename T1, typename T2> |
| auto_binary<Op> make_auto(Op op, const T1 &arg1, const T2 &arg2, bool destruct = true) |
| { |
| return auto_binary<Op>(op, arg1, arg2, destruct); |
| } |
| |
| |
| |
| |
| |
| template <typename T, T val> |
| class auto_reset |
| { |
| typedef T var_type; |
| |
| public: |
| var_type &m_var; |
| |
| public: |
| auto_reset(var_type &var) : m_var(var) {} |
| ~auto_reset() { m_var = val; } |
| |
| private: |
| auto_reset(const auto_reset &); |
| auto_reset &operator=(const auto_reset &); |
| }; |
| |
| |
| |
| |
| |
| template <typename T> |
| struct auto_backup { |
| typedef T var_type; |
| |
| public: |
| var_type m_backup; |
| var_type *m_original; |
| |
| public: |
| auto_backup() : m_original() {} |
| auto_backup(var_type &original) : m_original(&original), m_backup(original) {} |
| auto_backup(var_type *original) : m_original(original) |
| { |
| if (m_original) |
| m_backup = *m_original; |
| } |
| ~auto_backup() |
| { |
| if (m_original) |
| *m_original = m_backup; |
| } |
| |
| void reset(T &original) |
| { |
| m_original = &original; |
| m_backup = original; |
| } |
| void reset(T *original) |
| { |
| m_original = original; |
| if (m_original) |
| m_backup = *original; |
| } |
| |
| T *release() |
| { |
| T *original = m_original; |
| m_original = 0; |
| return original; |
| } |
| |
| private: |
| auto_backup(const auto_backup &); |
| auto_backup &operator=(const auto_backup &); |
| }; |
| |
| } |
| |
| #endif |