An experimental design for a property library for C++.
- See test for examples.
 
#include "libproperty/property.hpp"
#include <iostream>
#include <string>
struct my_class {
  int const& my_getter() const { return property.value; }
  int const& my_setter(std::string const& x) {
    return property.value = atoi(x.c_str());
  }
  LIBPROPERTY_PROPERTY((int), property, my_getter, my_setter, my_class);
};
int main() {
  my_class a;
  a.property = "5";
  std::cout << "should print 8: " << a.property + 3 << '\n';
  std::cout << "sizeof(a): " << sizeof(a)
            << " == sizeof(int): " << sizeof(int) << '\n';
}For the public interface, see the main source file.
libproperty may create any number of static member functions and types inside
your class where you use the macros.
All names of objects created inside your class begin with _libproperty__.
- The layout of your type will be exactly the same as if you defined a
variable of type Tinstead, whereTis thetypeparameter to the definition macro.
- The only new member of your class has the name name.
- The macros may not create any virtualfunctions.
This means you can rely on the layout of your class. The layout is guaranteed to
be the same as the type you supply to the creation macro.
LIBPROPERTY_WRAPPED((type), name, host_type); // recommended
LIBPROPERTY_PROPERTY((type), name, getter_name, setter_name, host_type);
LIBPROPERTY_PROPERTY2((type), name, getter_addr, setter_addr, host_type);
LIBPROPERTY_EMPTY_PROPERTY((type), name, getter_name, setter_name, host_type);
LIBPROPERTY_EMPTY_PROPERTY2((type), name, getter_addr, setter_addr, host_type);Defines a property with name name inside host_type that holds a type. The
value of the property is accessible using name.value from within the class.
Must be used within host_type definition.
The getter and setter must be methods of the host type.
The getter_name and setter_name parameters are just names of methods. They
are short-hands for when the getter and setter are not templates.
The getter_addr and setter_addr are the addresses of the getter and
setter member functions. Use them when you need to instantiate the getter and
setter templates by casting them to a member function pointer of the required
type.
The host type is the name of your class. Since these macros must be used
inside the class definition, you may omit all template parameters.
The macros above create a rw_property instance. Each one has a unique type
that carries the type, the host, and a name-derived type tag. These are used
to power the library machinery. It only has one member: T value, and it is
private. However, since the host class is declared a friend of the property
class, the host's methods are allowed access to the value member.
Its copy and move constructors, default constructor, destructor, and copy and move-assignment operators are defined private, thus only permitting the host class to copy the object.
The only other parts of the interface of note are the conversion operator to anything the getter produces, and an assignment operator from anything that the setter will accept as a parameter.
TODO: write examples for all of the above-mentioned corner cases.
Classes that use properties don't inflate (classes that just use the getter/setter capabilities do inflate - one needs at least one byte per class).
   auto x = y.property;
does not work - the copy constructor is private, as are assignment operators for the property type. It is therefore hard to copy it out of the class, where accessing it would cause extreme havoc (don't do that!).
The first version was started by Viktor Korsun.
He have a full-length talk about it at CppCon 2015, which is when Gašper Ažman re-wrote it overnight and gave a lightning talk improving on Viktor's concept the next day.
The current library also owes some conceptual ideas about metaprogrammimng to Louis Dionne, our dear author of boost.hana.
- move / copy actually does what it's supposed to
- getter and setter are members, not functions
- the value category of data is correct and gets correctly forwarded to the setter
- test where typeand getters are templated methods (to see macro problems)
- test regular inheritance hierarchies
- properties in base
- properties in derived
- properties in sibling (top and bottom sibling)
- crtp
 
- test virtual inheritance hierarchies
- auto x = y.propdoesn't compile.
- noexcept / sfinae / constexpr correctness
- ask Vittorio for some help, most likely
 
- in-place constructors? It is a container...
- constexpr is difficult because reinterpret_castdoesn't work constexpr