Git Product home page Git Product logo

xproperty's Introduction

xproperty

GithubActions Documentation Status Join the Gitter Chat

C++ properties and observer pattern

Introduction

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

Installation

xproperty is a header-only library. We provide a package for the mamba (or conda) package manager.

mamba install -c conda-forge xproperty

Or you can directly install it from the sources:

cmake -DCMAKE_INSTALL_PREFIX=your_install_prefix
make install

Documentation

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

http://xproperty.readthedocs.io/

Dependencies

xproperty depends on nlohmann_json.

Versions prior to 0.12.0, also depend on the xtl library.

xproperty xtl
0.11.0 >=0.7.0,<0.8
0.10.4 >=0.6.11,<0.7
0.10.3 >=0.6.11,<0.7
0.10.2 >=0.6.11,<0.7
0.10.1 >=0.6.11,<0.7
0.10.x >=0.6.11,<0.7
0.9.x >=0.6.11,<0.7
0.8.x >=0.5.0,<0.7
0.7.x ^0.4.0
0.6.x ^0.3.5

Usage

  • 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: " << f.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

foo.bar = 1.0;                           // Assigning a valid value
                                         // The notifier prints "Observer: New value of bar: 1"
std::cout << foo.bar << std::endl;       // Outputs 1.0

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

Shortcuts to link properties of observed objects

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

// Link `source.bar` and `target.baz`
XDLINK(source, bar, target, baz);

source.bar = 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. Besides, they can also be installed from conda-forge.

mamba install -c conda-forge gtest cmake

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

mkdir build
cd build
cmake -DBUILD_TESTS=ON ..
make -j2 xtest

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

cd test
mamba env create -f ./test-environment.yml
source activate test-xproperty
cd ..
cmake -DBUILD_TESTS=ON .
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 mamba or conda

mamba install -c conda-forge breathe

Finally, build the documentation with

make html

from the docs subdirectory.

License

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.

xproperty's People

Contributors

gouarin avatar johanmabille avatar myd7349 avatar serge-sans-paille avatar sylvaincorlay avatar wolfv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

xproperty's Issues

Check presence of observers and validators in owner

In xproperty.hpp, properties call methods on the owner.

    template <class T, class O, class D>
    template <class V>
    inline auto xproperty<T, O, D>::operator=(V&& value) -> reference
    {
        m_value = owner()->template invoke_validators<derived_type>(std::forward<V>(value));
        owner()->notify(derived_cast());
        owner()->template invoke_observers<derived_type>();
        return m_value;
    }

If we check that the methods exist at compile time and only call them if it is the case, we can prevent the requirement on the owner to have certain methods.

Changing the signature of notify

Currently, notify is a template function whose parameter type must be a property. WIth the recent simplification of the xproperty type, it could be worth templating this method with the value_type instead:

template <class D>
template <class T>
inline void xobserved<D>::notify(const T&, const std::string&)
{
}

This would reduce the number of template instantiations, and thus the compilation time. Besides, if the notify function of property owner is not trivial, this could reduce the size of the binary.

XDLINK - Copy without Transform

Copy without doing a computation or transforming the value might be less useful hence it might be worthwhile to add closure to do it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.