File: _satisfies_interface.hpp

package info (click to toggle)
r-bioc-alabaster.base 1.6.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,652 kB
  • sloc: cpp: 11,377; sh: 29; makefile: 2
file content (74 lines) | stat: -rw-r--r-- 2,564 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef TAKANE_SATISFIES_INTERFACE_HPP
#define TAKANE_SATISFIES_INTERFACE_HPP

#include <unordered_set>
#include <unordered_map>
#include <string>
#include "_derived_from.hpp"

/**
 * @file _satisfies_interface.hpp
 * @brief Check if an object interface is satisfied.
 */

namespace takane {

/**
 * @cond
 */
namespace internal_satisfies_interface {

inline auto default_registry() {
    std::unordered_map<std::string, std::unordered_set<std::string> > registry;
    registry["SIMPLE_LIST"] = { "simple_list" };
    registry["DATA_FRAME"] = { "data_frame" };
    registry["SUMMARIZED_EXPERIMENT"] = { "summarized_experiment", "vcf_experiment" };
    return registry;
}

inline bool check(const std::string& type, const std::string& interface, const std::unordered_map<std::string, std::unordered_set<std::string> >& registry, const Options& options) {
    auto it = registry.find(interface);
    if (it == registry.end()) {
        return false;
    }

    const auto& listing = it->second;
    if (listing.find(type) != listing.end()) {
        return true;
    }

    for (const auto& d : listing) {
        if (derived_from(type, d, options)) {
            return true;
        }
    }

    return false;
}

}
/**
 * @endcond
 */

/**
 * Check whether a particular object type satisfies a particular object interface.
 * This can be used by specifications to check that child components satisfy certain user-level expectations for an abstract object (e.g., data frames, lists).
 *
 * Applications can extend the **takane** framework by adding custom types to `Options::custom_satisfies_interface`.
 * This extends the default relationships whereby `satisfies_interface()` will take the union of all object types in the default and custom sets.
 * Note that, if a type is included in a particular set, it is not necessary to add its derived types, as `satisfies_interface()` will automatically call `derived_from()`.
 *
 * @param type Object type.
 * @param interface Interface type.
 * @param options Validation options, containing custom object interface relationships.
 * @returns Whether `type` satisfies `interface`.
 */
inline bool satisfies_interface(const std::string& type, const std::string& interface, const Options& options) {
    static const auto satisfies_interface_registry = internal_satisfies_interface::default_registry();
    return internal_satisfies_interface::check(type, interface, satisfies_interface_registry, options) || internal_satisfies_interface::check(type, interface, options.custom_satisfies_interface, options);
}

}

#endif