Ddoc $(SPEC_S Properties, $(P Every type and expression has properties that can be queried:) $(TABLE2 Property Examples, $(TR $(TH Expression) $(TH Value)) $(TR $(TD int.sizeof) $(TD yields 4)) $(TR $(TD float.nan) $(TD yields the floating point nan (Not A Number) value)) $(TR $(TD (float).nan) $(TD yields the floating point nan value)) $(TR $(TD (3).sizeof) $(TD yields 4 (because 3 is an int))) $(TR $(TD 2.sizeof) $(TD syntax error, since "2." is a floating point number)) $(TR $(TD int.init) $(TD default initializer for int's)) $(TR $(TD int.mangleof) $(TD yields the string "i")) $(TR $(TD int.stringof) $(TD yields the string "int")) $(TR $(TD (1+2).stringof) $(TD yields the string "1 + 2")) ) $(BR) $(TABLE2 Properties for All Types, $(TR $(TH Property) $(TH Description)) $(TR $(TD $(LINK2 #init, .init)) $(TD initializer)) $(TR $(TD $(LINK2 #sizeof, .sizeof)) $(TD size in bytes (equivalent to C's sizeof(type)))) $(TR $(TD $(LINK2 #alignof, .alignof)) $(TD alignment size)) $(TR $(TD $(LINK2 #mangleof, .mangleof)) $(TD string representing the $(SINGLEQUOTE mangled) representation of the type)) $(TR $(TD $(LINK2 #stringof, .stringof)) $(TD string representing the source representation of the type)) ) $(BR) $(TABLE2 Properties for Integral Types, $(TR $(TH Property) $(TH Description)) $(TR $(TD .init) $(TD initializer (0))) $(TR $(TD .max) $(TD maximum value)) $(TR $(TD .min) $(TD minimum value)) ) $(BR) $(TABLE2 Properties for Floating Point Types, $(TR $(TH Property) $(TH Description)) $(TR $(TD .init) $(TD initializer (NaN))) $(TR $(TD .infinity) $(TD infinity value)) $(TR $(TD .nan) $(TD NaN value)) $(TR $(TD .dig) $(TD number of decimal digits of precision)) $(TR $(TD .epsilon) $(TD smallest increment to the value 1)) $(TR $(TD .mant_dig) $(TD number of bits in mantissa)) $(TR $(TD .max_10_exp) $(TD maximum int value such that 10max_10_exp is representable)) $(TR $(TD .max_exp) $(TD maximum int value such that 2max_exp-1 is representable)) $(TR $(TD .min_10_exp) $(TD minimum int value such that 10min_10_exp is representable as a normalized value)) $(TR $(TD .min_exp) $(TD minimum int value such that 2min_exp-1 is representable as a normalized value)) $(TR $(TD .max) $(TD largest representable value that's not infinity)) $(V1 $(TR $(TD .min) $(TD smallest representable normalized value that's not 0))) $(V2 $(TR $(TD .min_normal) $(TD smallest representable normalized value that's not 0))) $(TR $(TD .re) $(TD real part)) $(TR $(TD .im) $(TD imaginary part)) ) $(BR) $(TABLE2 Properties for Class Types, $(TR $(TH Property) $(TH Description)) $(TR $(TD $(LINK2 #classinfo, .classinfo)) $(TD Information about the dynamic type of the class)) ) $(SECTION2 $(LNAME2 init, .init) Property, $(P $(B .init) produces a constant expression that is the default initializer. If applied to a type, it is the default initializer for that type. If applied to a variable or field, it is the default initializer for that variable or field. For example: ) ---------------- int a; int b = 1; typedef int t = 2; t c; t d = cast(t)3; int.init // is 0 a.init // is 0 b.init // is 0 t.init // is 2 c.init // is 2 d.init // is 2 struct Foo { int a; int b = 7; } Foo.a.init // is 0 Foo.b.init // is 7 ---------------- ) $(SECTION2 $(LNAME2 stringof, .stringof) Property, $(P $(B .stringof) produces a constant string that is the source representation of its prefix. If applied to a type, it is the string for that type. If applied to an expression, it is the source representation of that expression. Semantic analysis is not done for that expression. For example: ) ---------------- struct Foo { } enum Enum { RED } typedef int myint; void main() { writefln((1+2).stringof); // "1 + 2" writefln(Foo.stringof); // "Foo" writefln(test.Foo.stringof); // "test.Foo" writefln(int.stringof); // "int" writefln((int*[5][]).stringof); // "int*[5][]" writefln(Enum.RED.stringof); // "Enum.RED" writefln(test.myint.stringof); // "test.myint" writefln((5).stringof); // "5" } ---------------- ) $(SECTION2 $(LNAME2 sizeof, .sizeof Property), $(P $(CODE $(I e).sizeof) gives the size in bytes of the expression $(I e). ) $(P When getting the size of a member, it is not necessary for there to be a $(I this) object: ) --- struct S { int a; static int foo() { return a.sizeof; // returns 4 } } void test() { int x = S.a.sizeof; // sets x to 4 } --- $(P $(CODE .sizeof) applied to a class object returns the size of the class reference, not the class instantiation.) ) $(SECTION2 $(LNAME2 alignof, .alignof Property), $(P $(CODE .alignof) gives the aligned size of an expression or type. For example, an aligned size of 1 means that it is aligned on a byte boundary, 4 means it is aligned on a 32 bit boundary. ) ) $(SECTION2 $(LNAME2 classinfo, .classinfo) Property, $(P $(CODE .classinfo) provides information about the dynamic type of a class object. $(V1 It returns a reference to type $(LINK2 phobos/object.html, object.ClassInfo).) $(V2 It returns a reference to type $(LINK2 phobos/object.html#TypeInfo_Class, object.TypeInfo_Class).) ) ) $(SECTION3 $(LNAME2 classproperties, User Defined Class and Struct Properties), $(P Properties are member functions that can be syntactically treated as if they were fields. Properties can be read from or written to. A property is read by calling a method with no arguments; a property is written by calling a method with its argument being the value it is set to. ) $(P A simple property would be:) $(V1 ---------------- struct Foo { int data() { return m_data; } // read property int data(int value) { return m_data = value; } // write property private: int m_data; } ---------------- ) $(V2 ---------------- struct Foo { @property int data() { return m_data; } // read property @property int data(int value) { return m_data = value; } // write property private: int m_data; } ---------------- $(P Properties are marked with the $(CODE @property) attribute. Properties may only have zero or one parameter, and may not be variadic. Property functions may not be overloaded with non-property functions. ) ) $(P To use it:) ---------------- int test() { Foo f; f.data = 3; // same as f.data(3); return f.data + 3; // same as return f.data() + 3; } ---------------- $(P The absence of a read method means that the property is write-only. The absence of a write method means that the property is read-only. Multiple write methods can exist; the correct one is selected using the usual function overloading rules. ) $(P In all the other respects, these methods are like any other methods. They can be static, have different linkages, $(V1 be overloaded with methods with multiple parameters,) have their address taken, etc. ) $(P $(B Note:) Properties currently cannot be the lvalue of an $(I op)=, ++, or -- operator. ) ) ) Macros: TITLE=Properties WIKI=Property