Page MenuHomePhorge

Abstraction.hpp
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

Abstraction.hpp

/***************************************************************************//**
*
* \file rosa/agent/Abstraction.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Definition of *abstraction* *functionality*.
*
******************************************************************************/
#ifndef ROSA_AGENT_ABSTRACTION_HPP
#define ROSA_AGENT_ABSTRACTION_HPP
#include "rosa/agent/Module.h"
#include "rosa/support/debug.hpp"
#include <algorithm>
#include <map>
namespace rosa {
namespace agent {
/// Abstracts values from a type to another one.
///
/// \tparam T type to abstract from
/// \tparam A type to abstract to
template <typename T, typename A> class Abstraction : public Module {
protected:
/// Value to abstract to by default.
const A Default;
public:
/// Creates an instance.
///
/// \param Default value to abstract to by default
Abstraction(const A Default) noexcept : Default(Default) {}
/// Destroys `this` object.
~Abstraction(void) = default;
/// Abstracts a value from type `T` to type `A`.
///
/// \note The default implementation always returns
/// `rosa::agent::Abstraction::Default`, hence the actual argument is ignored.
///
/// \return the abstracted value
virtual A operator()(const T &) const noexcept { return Default; }
};
/// Implements `rosa::agent::Abstraction` as a `std::map` from a type to another
/// one.
///
/// \note This implementation is supposed to be used to abstract between
/// enumeration types, which is statically enforced.
///
/// \tparam T type to abstract from
/// \tparam A type to abstract to
template <typename T, typename A>
class MapAbstraction : public Abstraction<T, A>, private std::map<T, A> {
// Make sure the actual type arguments are enumerations.
STATIC_ASSERT((std::is_enum<T>::value && std::is_enum<A>::value),
"mapping not enumerations");
// Bringing into scope inherited members.
using Abstraction<T, A>::Default;
using std::map<T, A>::end;
using std::map<T, A>::find;
public:
/// Creates an instance by initializing the underlying `std::map`.
///
/// \param Map the mapping to do abstraction according to
/// \param Default value to abstract to by default
MapAbstraction(const std::map<T, A> &Map, const A Default) noexcept
: Abstraction<T, A>(Default),
std::map<T, A>(Map) {}
/// Destroys `this` object.
~MapAbstraction(void) = default;
/// Abstracts a value from type `T` to type `A` based on the set mapping.
///
/// Results in the value associated by the set mapping to the argument, or
/// `rosa::agent::MapAbstraction::Default` if the actual argument is not
/// associated with anything by the set mapping.
///
/// \param V value to abstract
///
/// \return the abstracted value based on the set mapping
A operator()(const T &V) const noexcept override {
const auto I = find(V);
return I == end() ? Default : *I;
}
};
/// Implements `rosa::agent::Abstraction` as a `std::map` from ranges of a type
/// to values of another type.
///
/// \note This implementation is supposed to be used to abstract ranges of
/// arithmetic types into enumerations, which is statically enforced.
///
/// \invariant The keys in the underlying `std::map` define valid ranges
/// `(first <= second)` and there are no overlapping ranges defined by the keys.
///
/// \tparam T type to abstract from
/// \tparam A type to abstract to
template <typename T, typename A>
class RangeAbstraction : public Abstraction<T, A>,
private std::map<std::pair<T, T>, A> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<T>::value), "abstracting not arithmetic");
STATIC_ASSERT((std::is_enum<A>::value), "abstracting not to enumeration");
// Bringing into scope inherited members.
using Abstraction<T, A>::Default;
using std::map<std::pair<T, T>, A>::begin;
using std::map<std::pair<T, T>, A>::end;
using std::map<std::pair<T, T>, A>::find;
public:
/// Creates an instance by Initializing the unserlying `std::map`.
///
/// \param Map the mapping to do abstraction according to
/// \param Default value to abstract to by default
///
/// \pre Each key defines a valid range `(first <= second)` and there are no
/// overlapping ranges defined by the keys.
RangeAbstraction(const std::map<std::pair<T, T>, A> &Map, const A &Default)
: Abstraction<T, A>(Default), std::map<std::pair<T, T>, A>(Map) {
// Sanity check.
ASSERT(std::all_of(
begin(), end(), [this](const std::pair<std::pair<T, T>, A> &P) {
return P.first.first <= P.first.second &&
std::all_of(++find(P.first), end(),
[&P](const std::pair<std::pair<T, T>, A> &R) {
// NOTE: Values in Map are sorted.
return P.first.first < P.first.second &&
P.first.second <= R.first.first ||
P.first.first == P.first.second &&
P.first.second < R.first.first;
});
}));
}
/// Destroys `this` object.
~RangeAbstraction(void) = default;
// Gives a value of type A associated by the underlying map to V of type T,
// or Default if no range containing V is defined.
/// Abstracts a value from type `T` to type `A` based on the set mapping.
///
/// Results in the value associated by the set mapping to the argument, or
/// `rosa::agent::RangeAbstraction::Default` if the actual argument is not
/// included in any of the ranges in the set mapping.
///
/// \param V value to abstract
///
/// \return the abstracted value based on the set mapping
A operator()(const T &V) const noexcept override {
auto I = begin();
bool Found = false; // Indicates if I refers to a matching range.
bool Failed = false; // Indicates if it is pointless to continue searching.
while (!Found && !Failed && I != end()) {
if (V < I->first.first) {
// No match so far and V is below the next range, never will match.
// \note Keys are sorted in the map.
Failed = true;
} else if (I->first.first <= V && V < I->first.second) {
// Matching range found.
Found = true;
} else {
// Cannot conclude in this step, move to the next range.
++I;
}
}
ASSERT(!Found || I != end());
return Found ? I->second : Default;
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_ABSTRACTION_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sun, Apr 12, 11:42 AM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
306286
Default Alt Text
Abstraction.hpp (6 KB)

Event Timeline