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