summaryrefslogtreecommitdiff
path: root/include/class.h
blob: 201f4de4bb0b13c3c285ff03e2d29a52eb6a33cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
 *  Class.h
 *
 *  When a class is registered in the extension, you need this helper class
 *  for that.
 *
 *  The use of it is simple:
 *
 *  Extension::add(Class<YourClass>);
 *
 *  Note that YourClass must extend from Php::Object
 *
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  changed by Valeriy Dmitriev <ufabiz@gmail.com>
 *  @copyright 2013 Copernica BV
 */

/**
 *  Forward declarations
 */
struct _zend_class_entry;

/**
 *  Set up namespace
 */
namespace Php {
 
/**
 *  Class definition of the class
 */
template <typename T>
class Class
{
public:
    /**
     *  Constructor
     */
    Class() {}
    
    /**
     *  Constructor with initializer list to define the properties
     *  @param  members
     */
    Class(const std::initializer_list<Member> &members, FlagClass flags = FlagClass(Zend::AccClass::NOSET)) : _members(members), _flags(flags) {}
    
    /**
     *  Move constructor
     *  @param  that
     */
    Class(Class &&that) : _members(std::move(that._members)), _flags(std::move(that._flags)) {}

    /**
     *  Copy constructor
     */
    Class(const Class &that) : _members(that._members), _flags(that._flags) {}
    
    /**
     *  Destructor
     */
    virtual ~Class() {}
    
    /**
     *  Construct an instance
     *  @return Base
     */
    Base* construct()
    {
        // allocate the object
        return new T();
    }

    /**
     *  Initialize the class
     *  This will declare all members
     *  @param entry
     */
    void initialize(struct _zend_class_entry *entry)
    {
        // loop through the members
        for (auto iter = _members.begin(); iter != _members.end(); iter++)
        {
            iter->declare(entry);
        }
    }
    
    /**
     *  Retrieve the functions
     *  @param  classname
     *  @return zend_function_entry*
     */
    struct _zend_function_entry *methods(const char *classname)
    {
        return _members.methods(classname);
    }
    
    /**
     *  Retrieve the int access types flags for PHP class
     *  @return int flags of access types for classes
     */
    int getFlags() {
        return _flags;
    }

protected:
    /**
     *  The initial arguments
     *  @var Members
     */
    Members _members;

private:
    /**
     *  The access types flags for class
     */
    FlagClass _flags;

};


/**
 *  Class definition of the ClassFlagged
 *  template ClassFlagged designed for easy instance of Class<T> for concrete flags
 */
template <typename T, Zend::AccClass Flags>
class ClassFlagged : public Class<T>
{
public:
    ClassFlagged() : Class<T>() {}
    ClassFlagged(const std::initializer_list<Member> &members) : Class<T>(members, FlagClass(Flags)) {}
};

template <typename T>
// C++11 analog of `typedef`. Equivalent to the following pseudocode: typedef ClassFlagged<T, Zend::AccClass::FINAL> FinalClass<T>;
using FinalClass    = ClassFlagged<T, Zend::AccClass::FINAL>;
template <typename T>
using AbstractClass = ClassFlagged<T, Zend::AccClass::ABSTRACT>;
template <typename T>
using Interface     = ClassFlagged<T, Zend::AccClass::INTERFACE>;
template <typename T>
using Trait         = ClassFlagged<T, Zend::AccClass::TRAIT>;

/**
 *  End of namespace
 */
}