Program Listing for File conditions.hpp

Return to documentation for file (include/nix/valid/conditions.hpp)

// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef NIX_CONDITIONS_H
#define NIX_CONDITIONS_H

#include <nix/Platform.hpp>
#include <nix/base/NamedEntity.hpp>
#include <nix/util/util.hpp>
#include <nix/valid/helper.hpp>
#include <nix/valid/result.hpp>
#include <nix/valid/checks.hpp>
#include <nix/valid/validator.hpp>

#include <string>
#include <functional>

namespace nix {
namespace valid {

    template<typename TOBJ, typename TBASEOBJ, typename TRET, typename TCHECK>
    condition
    must(const TOBJ &parent, TRET(TBASEOBJ::*get)(void)const, const TCHECK &check,
         const std::string &msg, const std::vector<condition> &subs = {}) {
        return [parent, get, check, msg, subs] () -> Result {
            bool errOccured = false;
            typedef decltype((parent.*get)()) return_type;
            return_type val;
            std::string id = nix::util::numToStr(
                                ID<hasID<TOBJ>::value>().get(parent)
                             );
            boost::optional<std::string> name = nix::getEntityName(parent);

            // execute getter call & check for error
            try {
                val = (parent.*get)();
            } catch (const std::exception&) {
                errOccured = true;
            }

            // compare value & check for validity
            if(errOccured || !check(val)) {
                return Result(Message(id, msg, name), none); // failed || error
            }

            // passed
            Result result = Result();
            for(auto &sub : subs) {
                result = result.concat( sub() );
            }
            return result;
        };
    }

    template<typename TOBJ, typename TBASEOBJ, typename TRET, typename TCHECK>
    condition
    should(const TOBJ &parent, TRET(TBASEOBJ::*get)(void)const, const TCHECK &check,
           const std::string &msg, const std::vector<condition> &subs = {}) {
        return [parent, get, check, msg, subs] () -> Result {
            bool errOccured = false;
            typedef decltype((parent.*get)()) return_type;
            return_type val;
            std::string id = nix::util::numToStr(
                                ID<hasID<TOBJ>::value>().get(parent)
                             );
            boost::optional<std::string> name = nix::getEntityName(parent);

            // execute getter call & check for error
            try {
                val = (parent.*get)();
            } catch (const std::exception&) {
                errOccured = true;
            }

            // compare value & check for validity
            if(errOccured || !check(val)) { // failed || error
                return Result(none, Message(id, msg, name));
            }

            // passed
            Result result = Result();
            for(auto &sub : subs) {
                result = result.concat( sub() );
            }
            return result;
        };
    }

    template<typename TOBJ, typename TBASEOBJ, typename TRET, typename TCHECK>
    condition
    could(const TOBJ &parent, TRET(TBASEOBJ::*get)(void)const, const TCHECK &check,
          const std::vector<condition> &subs = {}) {
        return [parent, get, check, subs] () -> Result {
            bool errOccured = false;
            typedef decltype((parent.*get)()) return_type;
            return_type val;

            // execute getter call & check for error
            try {
                val = (parent.*get)();
            } catch (const std::exception&) {
                errOccured = true;
            }

            // compare value & check for validity
            if(errOccured || !check(val)) { // failed || error
                return Result();
            }

            // passed
            Result result = Result();
            for(auto &sub : subs) {
                result = result.concat( sub() );
            }
            return result;
        };
    }

} // namespace valid
} // namespace nix

#endif // NIX_CONDITIONS_H