Traitlets-like C++ properties and implementation of the observer pattern
C++ CMake Jupyter Notebook
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.


Travis Appveyor Documentation Status Join the Gitter Chat

C++ properties and observer pattern


xproperty is a C++ library providing traitlets-style properties.

xproperty provides an implementation of the observer patterns relying on C++ template and preprocessor metaprogramming techniques.

Properies of observed objects have no additional memory footprint than the value they hold. The assignment of a new value is simply replaced at compiled time by

  • the call to the validator for that property
  • the actual underlying assigment
  • the call to the observor for that property.

We also provide the implementation of an xobserved class whose static validator and observer are bound to a dynamic unordered map of callbacks that can be registered dynamically.

xproperty requires a modern C++ compiler supporting C++14. The following C++ compilers are supported:

  • On Windows platforms, Visual C++ 2015 Update 2, or more recent
  • On Unix platforms, gcc 4.9 or a recent version of Clang


xproperty is a header-only library. We provide a package for the conda package manager.

conda install -c conda-forge xproperty

Or you can directly install it from the sources:

cmake -DCMAKE_INSTALL_PREFIX=your_install_prefix
make install


To get started with using xproperty, check out the full documentation


xproperty depends on the xtl library.

xproperty xtl
master ^0.4.0
0.7.0 ^0.4.0
0.6.0 ^0.3.5


  • Declaring an observed object Foo with two properties named bar and baz of type double.
  • Registering a validator, executed prior to assignment, which can potentially coerce the proposed value.
  • Registering a notifier, executed after the assignement.
#include <iostream>
#include <stdexcept>

#include "xproperty/xobserved.hpp"

struct Foo : public xp::xobserved<Foo>
    XPROPERTY(double, Foo, bar);
    XPROPERTY(double, Foo, baz);

Registering an observer and a validator

Foo foo;

XOBSERVE(foo, bar, [](Foo& f)
    std::cout << "Observer: New value of bar: " << << std::endl;

XVALIDATE(foo, bar, [](Foo&, double& proposal)
    std::cout << "Validator: Proposal: " << proposal << std::endl;
    if (proposal < 0)
        throw std::runtime_error("Only non-negative values are valid.");
    return proposal;

Testing the validated and observed properties = 1.0;                           // Assigning a valid value
                                         // The notifier prints "Observer: New value of bar: 1"
std::cout << << std::endl;       // Outputs 1.0

{ = -1.0;                      // Assigning an invalid value
catch (...)
    std::cout << << std::endl;   // Still outputs 1.0

Shortcuts to link properties of observed objects

// Create two observed objects
Foo source, target; = 1.0;

// Link `` and `target.baz`
XDLINK(source, bar, target, baz); = 2.0;
std::cout << target.baz << std::endl;    // Outputs 2.0

Building and Running the Tests

Building the tests requires the GTest testing framework and cmake.

gtest and cmake are available as a packages for most linux distributions. Besideds, they can also be installed with the conda package manager (even on windows):

conda install -c conda-forge gtest cmake

Once gtest and cmake are installed, you can build and run the tests:

mkdir build
cd build
make -j2 xtest

In the context of continuous integration with Travis CI, tests are run in a conda environment, which can be activated with

cd test
conda env create -f ./test-environment.yml
source activate test-xproperty
cd ..
make -j2 xtest

Building the HTML Documentation

xpropery's documentation is built with three tools

While doxygen must be installed separately, you can install breathe by typing

pip install breathe

Breathe can also be installed with conda

conda install -c conda-forge breathe

Finally, build the documentation with

make html

from the docs subdirectory.


We use a shared copyright model that enables all contributors to maintain the copyright on their contributions.

This software is licensed under the BSD-3-Clause license. See the LICENSE file for details.