<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include "documentdbconfigmanager.h"
#include <vespa/log/log.h>
#include <vespa/searchcommon/common/schemaconfigurer.h>
#include <vespa/searchlib/index/schemautil.h>
LOG_SETUP(".proton.server.documentdbconfigmanager");
#include <vespa/config/helper/legacy.h>
#include <vespa/config/file_acquirer/file_acquirer.h>

using namespace config;
using namespace vespa::config::search::core;
using namespace vespa::config::search::summary;
using namespace vespa::config::search;

using document::DocumentTypeRepo;
using search::TuneFileDocumentDB;
using search::index::Schema;
using search::index::SchemaBuilder;
using fastos::TimeStamp;

// RankingConstantsConfigBuilder
// RankingConstantsConfig

namespace proton {

const ConfigKeySet
DocumentDBConfigManager::createConfigKeySet() const
{
    ConfigKeySet set;
    set.add<RankProfilesConfig,
            RankingConstantsConfig,
            IndexschemaConfig,
            AttributesConfig,
            SummaryConfig,
            SummarymapConfig,
            JuniperrcConfig>(_configId);
    set.add(_extraConfigKeys);
    return set;
}

Schema::SP
DocumentDBConfigManager::
buildNewSchema(const AttributesConfig & newAttributesConfig,
               const SummaryConfig & newSummaryConfig,
               const IndexschemaConfig & newIndexschemaConfig)
{
    // Called with lock held
    Schema::SP schema(new Schema);
    SchemaBuilder::build(newAttributesConfig, *schema);
    SchemaBuilder::build(newSummaryConfig, *schema);
    SchemaBuilder::build(newIndexschemaConfig, *schema);
    return schema;
}

Schema::SP
DocumentDBConfigManager::
buildSchema(const AttributesConfig & newAttributesConfig,
            const SummaryConfig & newSummaryConfig,
            const IndexschemaConfig & newIndexschemaConfig)
{
    // Called with lock held
    Schema::SP oldSchema;
    if (_pendingConfigSnapshot.get() != NULL)
        oldSchema = _pendingConfigSnapshot->getSchemaSP();
    if (oldSchema.get() == NULL)
        return buildNewSchema(newAttributesConfig,
                              newSummaryConfig, newIndexschemaConfig);
    const DocumentDBConfig &old = *_pendingConfigSnapshot;
    if (old.getAttributesConfig() != newAttributesConfig ||
        old.getSummaryConfig() != newSummaryConfig ||
        old.getIndexschemaConfig() != newIndexschemaConfig) {
        Schema::SP schema(buildNewSchema(newAttributesConfig,
                                  newSummaryConfig, newIndexschemaConfig));
        return (*oldSchema == *schema) ? oldSchema : schema;
    }
    return oldSchema;
}

static DocumentDBMaintenanceConfig::SP
buildMaintenanceConfig(const BootstrapConfig::SP &bootstrapConfig,
                       const vespalib::string &docTypeName)
{
    typedef ProtonConfig::Documentdb DdbConfig;
    ProtonConfig &proton(bootstrapConfig->getProtonConfig());

    TimeStamp visibilityDelay;
    // Use document type to find document db config in proton config
    uint32_t index;
    for (index = 0; index < proton.documentdb.size(); ++index) {
        const DdbConfig &ddbConfig = proton.documentdb[index];
        if (docTypeName == ddbConfig.inputdoctypename)
            break;
    }
    double pruneRemovedDocumentsInterval = proton.pruneremoveddocumentsinterval;
    double pruneRemovedDocumentsAge = proton.pruneremoveddocumentsage;

    if (index < proton.documentdb.size()) {
        const DdbConfig &ddbConfig = proton.documentdb[index];
        visibilityDelay = TimeStamp::Seconds(std::min(proton.maxvisibilitydelay, ddbConfig.visibilitydelay));
    }
    return DocumentDBMaintenanceConfig::SP(
            new DocumentDBMaintenanceConfig(
                    DocumentDBPruneRemovedDocumentsConfig(
                            pruneRemovedDocumentsInterval,
                            pruneRemovedDocumentsAge),
                    DocumentDBHeartBeatConfig(),
                    DocumentDBWipeOldRemovedFieldsConfig(
                            proton.wipeoldremovedfieldsinterval,
                            proton.wipeoldremovedfieldsage),
                    proton.grouping.sessionmanager.pruning.interval,
                    visibilityDelay,
                    DocumentDBLidSpaceCompactionConfig(
                            proton.lidspacecompaction.interval,
                            proton.lidspacecompaction.allowedlidbloat,
                            proton.lidspacecompaction.allowedlidbloatfactor),
                    AttributeUsageFilterConfig(
                            proton.writefilter.attribute.enumstorelimit,
                            proton.writefilter.attribute.multivaluelimit),
                    proton.writefilter.sampleinterval));
}

void
DocumentDBConfigManager::update(const ConfigSnapshot & snapshot)
{
    typedef DocumentDBConfig::RankProfilesConfigSP RankProfilesConfigSP;
    typedef DocumentDBConfig::RankingConstantsConfigSP RankingConstantsConfigSP;
    typedef DocumentDBConfig::IndexschemaConfigSP IndexschemaConfigSP;
    typedef DocumentDBConfig::AttributesConfigSP AttributesConfigSP;
    typedef DocumentDBConfig::SummaryConfigSP SummaryConfigSP;
    typedef DocumentDBConfig::SummarymapConfigSP SummarymapConfigSP;
    typedef DocumentDBConfig::JuniperrcConfigSP JuniperrcConfigSP;
    typedef DocumentDBConfig::MaintenanceConfigSP MaintenanceConfigSP;

    DocumentDBConfig::SP current = _pendingConfigSnapshot;
    RankProfilesConfigSP newRankProfilesConfig;
    RankingConstantsConfigSP newRankingConstantsConfig;
    IndexschemaConfigSP newIndexschemaConfig;
    AttributesConfigSP newAttributesConfig;
    SummaryConfigSP newSummaryConfig;
    SummarymapConfigSP newSummarymapConfig;
    JuniperrcConfigSP newJuniperrcConfig;
    MaintenanceConfigSP oldMaintenanceConfig;
    MaintenanceConfigSP newMaintenanceConfig;

    if (!_ignoreForwardedConfig) {
        if (_bootstrapConfig->getDocumenttypesConfigSP().get() == NULL ||
            _bootstrapConfig->getDocumentTypeRepoSP().get() == NULL ||
            _bootstrapConfig->getProtonConfigSP().get() == NULL ||
            _bootstrapConfig->getTuneFileDocumentDBSP().get() == NULL)
            return;
    }

    int64_t generation = snapshot.getGeneration();
    LOG(debug,
        "Forwarded generation %" PRId64 ", generation %" PRId64,
        _bootstrapConfig->getGeneration(), generation);
    if (!_ignoreForwardedConfig &&
        _bootstrapConfig->getGeneration() != generation)
            return;

    int64_t currentGeneration = -1;
    if (current.get() != NULL) {
        newRankProfilesConfig = current->getRankProfilesConfigSP();
        newRankingConstantsConfig = current->getRankingConstantsConfigSP();
        newIndexschemaConfig = current->getIndexschemaConfigSP();
        newAttributesConfig = current->getAttributesConfigSP();
        newSummaryConfig = current->getSummaryConfigSP();
        newSummarymapConfig = current->getSummarymapConfigSP();
        newJuniperrcConfig = current->getJuniperrcConfigSP();
        oldMaintenanceConfig = current->getMaintenanceConfigSP();
        currentGeneration = current->getGeneration();
    }

    if (snapshot.isChanged<RankProfilesConfig>(_configId, currentGeneration)) {
        newRankProfilesConfig =
            RankProfilesConfigSP(
                    snapshot.getConfig<RankProfilesConfig>(_configId).
                    release());
    }
    if (snapshot.isChanged<RankingConstantsConfig>(_configId, currentGeneration)) {
        newRankingConstantsConfig =
            RankingConstantsConfigSP(
                    snapshot.getConfig<RankingConstantsConfig>(_configId)
                    .release());
        const vespalib::string &spec = _bootstrapConfig->getFiledistributorrpcConfig().connectionspec;
        if (spec != "") {
            config::RpcFileAcquirer fileAcquirer(spec);
            for (const RankingConstantsConfig::Constant &rc : newRankingConstantsConfig->constant) {
                vespalib::string filePath = fileAcquirer.wait_for(rc.fileref, 5*60);
                fprintf(stderr, "GOT file-acq PATH is: %s (ref %s for name %s type %s)\n",
                        filePath.c_str(), rc.fileref.c_str(), rc.name.c_str(), rc.type.c_str());
            }
        }
    }
    if (snapshot.isChanged<IndexschemaConfig>(_configId, currentGeneration)) {
        std::unique_ptr<IndexschemaConfig> indexschemaConfig =
            snapshot.getConfig<IndexschemaConfig>(_configId);
        search::index::Schema schema;
        search::index::SchemaBuilder::build(*indexschemaConfig, schema);
        if (!search::index::SchemaUtil::validateSchema(schema)) {
            LOG(error,
                "Cannot use bad index schema, validation failed");
            abort();
        }
        newIndexschemaConfig =
            IndexschemaConfigSP(indexschemaConfig.release());
    }
    if (snapshot.isChanged<AttributesConfig>(_configId, currentGeneration))
        newAttributesConfig =
            AttributesConfigSP(snapshot.getConfig<AttributesConfig>(_configId).
                               release());
    if (snapshot.isChanged<SummaryConfig>(_configId, currentGeneration))
        newSummaryConfig =
            SummaryConfigSP(snapshot.getConfig<SummaryConfig>(_configId).
                            release());
    if (snapshot.isChanged<SummarymapConfig>(_configId, currentGeneration))
        newSummarymapConfig =
            SummarymapConfigSP(snapshot.getConfig<SummarymapConfig>(_configId).
                               release());
    if (snapshot.isChanged<JuniperrcConfig>(_configId, currentGeneration))
        newJuniperrcConfig =
            JuniperrcConfigSP(
                    snapshot.getConfig<JuniperrcConfig>(_configId).release());

    Schema::SP schema(buildSchema(*newAttributesConfig,
                                  *newSummaryConfig,
                                  *newIndexschemaConfig));
    newMaintenanceConfig = buildMaintenanceConfig(_bootstrapConfig,
                                                  _docTypeName);
    if (newMaintenanceConfig.get() != NULL &&
        oldMaintenanceConfig.get() != NULL &&
        *newMaintenanceConfig == *oldMaintenanceConfig) {
        newMaintenanceConfig = oldMaintenanceConfig;
    }
    ConfigSnapshot extraConfigs(snapshot.subset(_extraConfigKeys));
    DocumentDBConfig::SP newSnapshot(
            new DocumentDBConfig(generation,
                                 newRankProfilesConfig,
                                 newRankingConstantsConfig,
                                 newIndexschemaConfig,
                                 newAttributesConfig,
                                 newSummaryConfig,
                                 newSummarymapConfig,
                                 newJuniperrcConfig,
                                 _bootstrapConfig->getDocumenttypesConfigSP(),
                                 _bootstrapConfig->getDocumentTypeRepoSP(),
                                 _bootstrapConfig->getTuneFileDocumentDBSP(),
                                 schema,
                                 newMaintenanceConfig,
                                 _configId,
                                 _docTypeName,
                                 extraConfigs));
    assert(newSnapshot->valid());
    {
        vespalib::LockGuard lock(_pendingConfigLock);
        _pendingConfigSnapshot = newSnapshot;
    }
}

DocumentDBConfigManager::
DocumentDBConfigManager(const vespalib::string &configId,
                        const vespalib::string &docTypeName)
    : _configId(configId),
      _docTypeName(docTypeName),
      _bootstrapConfig(),
      _pendingConfigSnapshot(),
      _ignoreForwardedConfig(true),
      _pendingConfigLock(),
      _extraConfigKeys()
{
}

void
DocumentDBConfigManager::
forwardConfig(const BootstrapConfig::SP & config)
{
    {
        if (!_ignoreForwardedConfig &&
            config->getGeneration() < _bootstrapConfig->getGeneration())
            return;	// Enforce time direction
        _bootstrapConfig = config;
        _ignoreForwardedConfig = false;
    }
}

} // namespace proton
<commit_msg>use LOG not fprintf<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include "documentdbconfigmanager.h"
#include <vespa/log/log.h>
#include <vespa/searchcommon/common/schemaconfigurer.h>
#include <vespa/searchlib/index/schemautil.h>
LOG_SETUP(".proton.server.documentdbconfigmanager");
#include <vespa/config/helper/legacy.h>
#include <vespa/config/file_acquirer/file_acquirer.h>

using namespace config;
using namespace vespa::config::search::core;
using namespace vespa::config::search::summary;
using namespace vespa::config::search;

using document::DocumentTypeRepo;
using search::TuneFileDocumentDB;
using search::index::Schema;
using search::index::SchemaBuilder;
using fastos::TimeStamp;

namespace proton {

const ConfigKeySet
DocumentDBConfigManager::createConfigKeySet() const
{
    ConfigKeySet set;
    set.add<RankProfilesConfig,
            RankingConstantsConfig,
            IndexschemaConfig,
            AttributesConfig,
            SummaryConfig,
            SummarymapConfig,
            JuniperrcConfig>(_configId);
    set.add(_extraConfigKeys);
    return set;
}

Schema::SP
DocumentDBConfigManager::
buildNewSchema(const AttributesConfig & newAttributesConfig,
               const SummaryConfig & newSummaryConfig,
               const IndexschemaConfig & newIndexschemaConfig)
{
    // Called with lock held
    Schema::SP schema(new Schema);
    SchemaBuilder::build(newAttributesConfig, *schema);
    SchemaBuilder::build(newSummaryConfig, *schema);
    SchemaBuilder::build(newIndexschemaConfig, *schema);
    return schema;
}

Schema::SP
DocumentDBConfigManager::
buildSchema(const AttributesConfig & newAttributesConfig,
            const SummaryConfig & newSummaryConfig,
            const IndexschemaConfig & newIndexschemaConfig)
{
    // Called with lock held
    Schema::SP oldSchema;
    if (_pendingConfigSnapshot.get() != NULL)
        oldSchema = _pendingConfigSnapshot->getSchemaSP();
    if (oldSchema.get() == NULL)
        return buildNewSchema(newAttributesConfig,
                              newSummaryConfig, newIndexschemaConfig);
    const DocumentDBConfig &old = *_pendingConfigSnapshot;
    if (old.getAttributesConfig() != newAttributesConfig ||
        old.getSummaryConfig() != newSummaryConfig ||
        old.getIndexschemaConfig() != newIndexschemaConfig) {
        Schema::SP schema(buildNewSchema(newAttributesConfig,
                                  newSummaryConfig, newIndexschemaConfig));
        return (*oldSchema == *schema) ? oldSchema : schema;
    }
    return oldSchema;
}

static DocumentDBMaintenanceConfig::SP
buildMaintenanceConfig(const BootstrapConfig::SP &bootstrapConfig,
                       const vespalib::string &docTypeName)
{
    typedef ProtonConfig::Documentdb DdbConfig;
    ProtonConfig &proton(bootstrapConfig->getProtonConfig());

    TimeStamp visibilityDelay;
    // Use document type to find document db config in proton config
    uint32_t index;
    for (index = 0; index < proton.documentdb.size(); ++index) {
        const DdbConfig &ddbConfig = proton.documentdb[index];
        if (docTypeName == ddbConfig.inputdoctypename)
            break;
    }
    double pruneRemovedDocumentsInterval = proton.pruneremoveddocumentsinterval;
    double pruneRemovedDocumentsAge = proton.pruneremoveddocumentsage;

    if (index < proton.documentdb.size()) {
        const DdbConfig &ddbConfig = proton.documentdb[index];
        visibilityDelay = TimeStamp::Seconds(std::min(proton.maxvisibilitydelay, ddbConfig.visibilitydelay));
    }
    return DocumentDBMaintenanceConfig::SP(
            new DocumentDBMaintenanceConfig(
                    DocumentDBPruneRemovedDocumentsConfig(
                            pruneRemovedDocumentsInterval,
                            pruneRemovedDocumentsAge),
                    DocumentDBHeartBeatConfig(),
                    DocumentDBWipeOldRemovedFieldsConfig(
                            proton.wipeoldremovedfieldsinterval,
                            proton.wipeoldremovedfieldsage),
                    proton.grouping.sessionmanager.pruning.interval,
                    visibilityDelay,
                    DocumentDBLidSpaceCompactionConfig(
                            proton.lidspacecompaction.interval,
                            proton.lidspacecompaction.allowedlidbloat,
                            proton.lidspacecompaction.allowedlidbloatfactor),
                    AttributeUsageFilterConfig(
                            proton.writefilter.attribute.enumstorelimit,
                            proton.writefilter.attribute.multivaluelimit),
                    proton.writefilter.sampleinterval));
}

void
DocumentDBConfigManager::update(const ConfigSnapshot & snapshot)
{
    typedef DocumentDBConfig::RankProfilesConfigSP RankProfilesConfigSP;
    typedef DocumentDBConfig::RankingConstantsConfigSP RankingConstantsConfigSP;
    typedef DocumentDBConfig::IndexschemaConfigSP IndexschemaConfigSP;
    typedef DocumentDBConfig::AttributesConfigSP AttributesConfigSP;
    typedef DocumentDBConfig::SummaryConfigSP SummaryConfigSP;
    typedef DocumentDBConfig::SummarymapConfigSP SummarymapConfigSP;
    typedef DocumentDBConfig::JuniperrcConfigSP JuniperrcConfigSP;
    typedef DocumentDBConfig::MaintenanceConfigSP MaintenanceConfigSP;

    DocumentDBConfig::SP current = _pendingConfigSnapshot;
    RankProfilesConfigSP newRankProfilesConfig;
    RankingConstantsConfigSP newRankingConstantsConfig;
    IndexschemaConfigSP newIndexschemaConfig;
    AttributesConfigSP newAttributesConfig;
    SummaryConfigSP newSummaryConfig;
    SummarymapConfigSP newSummarymapConfig;
    JuniperrcConfigSP newJuniperrcConfig;
    MaintenanceConfigSP oldMaintenanceConfig;
    MaintenanceConfigSP newMaintenanceConfig;

    if (!_ignoreForwardedConfig) {
        if (_bootstrapConfig->getDocumenttypesConfigSP().get() == NULL ||
            _bootstrapConfig->getDocumentTypeRepoSP().get() == NULL ||
            _bootstrapConfig->getProtonConfigSP().get() == NULL ||
            _bootstrapConfig->getTuneFileDocumentDBSP().get() == NULL)
            return;
    }

    int64_t generation = snapshot.getGeneration();
    LOG(debug,
        "Forwarded generation %" PRId64 ", generation %" PRId64,
        _bootstrapConfig->getGeneration(), generation);
    if (!_ignoreForwardedConfig &&
        _bootstrapConfig->getGeneration() != generation)
            return;

    int64_t currentGeneration = -1;
    if (current.get() != NULL) {
        newRankProfilesConfig = current->getRankProfilesConfigSP();
        newRankingConstantsConfig = current->getRankingConstantsConfigSP();
        newIndexschemaConfig = current->getIndexschemaConfigSP();
        newAttributesConfig = current->getAttributesConfigSP();
        newSummaryConfig = current->getSummaryConfigSP();
        newSummarymapConfig = current->getSummarymapConfigSP();
        newJuniperrcConfig = current->getJuniperrcConfigSP();
        oldMaintenanceConfig = current->getMaintenanceConfigSP();
        currentGeneration = current->getGeneration();
    }

    if (snapshot.isChanged<RankProfilesConfig>(_configId, currentGeneration)) {
        newRankProfilesConfig =
            RankProfilesConfigSP(
                    snapshot.getConfig<RankProfilesConfig>(_configId).
                    release());
    }
    if (snapshot.isChanged<RankingConstantsConfig>(_configId, currentGeneration)) {
        newRankingConstantsConfig =
            RankingConstantsConfigSP(
                    snapshot.getConfig<RankingConstantsConfig>(_configId)
                    .release());
        const vespalib::string &spec = _bootstrapConfig->getFiledistributorrpcConfig().connectionspec;
        if (spec != "") {
            config::RpcFileAcquirer fileAcquirer(spec);
            for (const RankingConstantsConfig::Constant &rc : newRankingConstantsConfig->constant) {
                vespalib::string filePath = fileAcquirer.wait_for(rc.fileref, 5*60);
                LOG(info, "GOT file-acq PATH is: %s (ref %s for name %s type %s)\n",
                    filePath.c_str(), rc.fileref.c_str(), rc.name.c_str(), rc.type.c_str());
            }
        }
    }
    if (snapshot.isChanged<IndexschemaConfig>(_configId, currentGeneration)) {
        std::unique_ptr<IndexschemaConfig> indexschemaConfig =
            snapshot.getConfig<IndexschemaConfig>(_configId);
        search::index::Schema schema;
        search::index::SchemaBuilder::build(*indexschemaConfig, schema);
        if (!search::index::SchemaUtil::validateSchema(schema)) {
            LOG(error,
                "Cannot use bad index schema, validation failed");
            abort();
        }
        newIndexschemaConfig =
            IndexschemaConfigSP(indexschemaConfig.release());
    }
    if (snapshot.isChanged<AttributesConfig>(_configId, currentGeneration))
        newAttributesConfig =
            AttributesConfigSP(snapshot.getConfig<AttributesConfig>(_configId).
                               release());
    if (snapshot.isChanged<SummaryConfig>(_configId, currentGeneration))
        newSummaryConfig =
            SummaryConfigSP(snapshot.getConfig<SummaryConfig>(_configId).
                            release());
    if (snapshot.isChanged<SummarymapConfig>(_configId, currentGeneration))
        newSummarymapConfig =
            SummarymapConfigSP(snapshot.getConfig<SummarymapConfig>(_configId).
                               release());
    if (snapshot.isChanged<JuniperrcConfig>(_configId, currentGeneration))
        newJuniperrcConfig =
            JuniperrcConfigSP(
                    snapshot.getConfig<JuniperrcConfig>(_configId).release());

    Schema::SP schema(buildSchema(*newAttributesConfig,
                                  *newSummaryConfig,
                                  *newIndexschemaConfig));
    newMaintenanceConfig = buildMaintenanceConfig(_bootstrapConfig,
                                                  _docTypeName);
    if (newMaintenanceConfig.get() != NULL &&
        oldMaintenanceConfig.get() != NULL &&
        *newMaintenanceConfig == *oldMaintenanceConfig) {
        newMaintenanceConfig = oldMaintenanceConfig;
    }
    ConfigSnapshot extraConfigs(snapshot.subset(_extraConfigKeys));
    DocumentDBConfig::SP newSnapshot(
            new DocumentDBConfig(generation,
                                 newRankProfilesConfig,
                                 newRankingConstantsConfig,
                                 newIndexschemaConfig,
                                 newAttributesConfig,
                                 newSummaryConfig,
                                 newSummarymapConfig,
                                 newJuniperrcConfig,
                                 _bootstrapConfig->getDocumenttypesConfigSP(),
                                 _bootstrapConfig->getDocumentTypeRepoSP(),
                                 _bootstrapConfig->getTuneFileDocumentDBSP(),
                                 schema,
                                 newMaintenanceConfig,
                                 _configId,
                                 _docTypeName,
                                 extraConfigs));
    assert(newSnapshot->valid());
    {
        vespalib::LockGuard lock(_pendingConfigLock);
        _pendingConfigSnapshot = newSnapshot;
    }
}

DocumentDBConfigManager::
DocumentDBConfigManager(const vespalib::string &configId,
                        const vespalib::string &docTypeName)
    : _configId(configId),
      _docTypeName(docTypeName),
      _bootstrapConfig(),
      _pendingConfigSnapshot(),
      _ignoreForwardedConfig(true),
      _pendingConfigLock(),
      _extraConfigKeys()
{
}

void
DocumentDBConfigManager::
forwardConfig(const BootstrapConfig::SP & config)
{
    {
        if (!_ignoreForwardedConfig &&
            config->getGeneration() < _bootstrapConfig->getGeneration())
            return;	// Enforce time direction
        _bootstrapConfig = config;
        _ignoreForwardedConfig = false;
    }
}

} // namespace proton
<|endoftext|>


<commit_before>#ifndef ENTT_ENTITY_HELPER_HPP
#define ENTT_ENTITY_HELPER_HPP

#include <type_traits>
#include "../config/config.h"
#include "../core/fwd.hpp"
#include "../core/type_traits.hpp"
#include "../signal/delegate.hpp"
#include "fwd.hpp"
#include "registry.hpp"

namespace entt {

/**
 * @brief Converts a registry to a view.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct as_view {
    /*! @brief Underlying entity identifier. */
    using entity_type = std::remove_const_t<Entity>;
    /*! @brief Type of registry to convert. */
    using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;

    /**
     * @brief Constructs a converter for a given registry.
     * @param source A valid reference to a registry.
     */
    as_view(registry_type &source) noexcept
        : reg{source} {}

    /**
     * @brief Conversion function from a registry to a view.
     * @tparam Exclude Types of components used to filter the view.
     * @tparam Component Type of components used to construct the view.
     * @return A newly created view.
     */
    template<typename Exclude, typename... Component>
    operator basic_view<entity_type, get_t<Component...>, Exclude>() const {
        return reg.template view<Component...>(Exclude{});
    }

private:
    registry_type ®
};

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_view(basic_registry<Entity> &) -> as_view<Entity>;

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_view(const basic_registry<Entity> &) -> as_view<const Entity>;

/**
 * @brief Converts a registry to a group.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct as_group {
    /*! @brief Underlying entity identifier. */
    using entity_type = std::remove_const_t<Entity>;
    /*! @brief Type of registry to convert. */
    using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;

    /**
     * @brief Constructs a converter for a given registry.
     * @param source A valid reference to a registry.
     */
    as_group(registry_type &source) noexcept
        : reg{source} {}

    /**
     * @brief Conversion function from a registry to a group.
     * @tparam Get Types of components observed by the group.
     * @tparam Exclude Types of components used to filter the group.
     * @tparam Owned Types of components owned by the group.
     * @return A newly created group.
     */
    template<typename Get, typename Exclude, typename... Owned>
    operator basic_group<entity_type, owned_t<Owned...>, Get, Exclude>() const {
        if constexpr(std::is_const_v<registry_type>) {
            return reg.template group_if_exists<Owned...>(Get{}, Exclude{});
        } else {
            return reg.template group<Owned...>(Get{}, Exclude{});
        }
    }

private:
    registry_type ®
};

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_group(basic_registry<Entity> &) -> as_group<Entity>;

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_group(const basic_registry<Entity> &) -> as_group<const Entity>;

/**
 * @brief Helper to create a listener that directly invokes a member function.
 * @tparam Member Member function to invoke on a component of the given type.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 * @param reg A registry that contains the given entity and its components.
 * @param entt Entity from which to get the component.
 */
template<auto Member, typename Entity = entity>
void invoke(basic_registry<Entity> &reg, const Entity entt) {
    static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
    delegate<void(basic_registry<Entity> &, const Entity)> func;
    func.template connect<Member>(reg.template get<member_class_t<decltype(Member)>>(entt));
    func(reg, entt);
}

/**
 * @brief Returns the entity associated with a given component.
 *
 * @warning
 * Currently, this function only works correctly with the default pool as it
 * makes assumptions about how the components are laid out.
 *
 * @tparam Entity A valid entity type (see entt_traits for more details).
 * @tparam Component Type of component.
 * @param reg A registry that contains the given entity and its components.
 * @param instance A valid component instance.
 * @return The entity associated with the given component.
 */
template<typename Entity, typename Component>
Entity to_entity(const basic_registry<Entity> &reg, const Component &instance) {
    const auto &storage = reg.template storage<Component>();
    const typename basic_registry<Entity>::base_type &base = storage;
    const auto *addr = std::addressof(instance);

    for(auto it = base.rbegin(), last = base.rend(); it < last; it += ENTT_PACKED_PAGE) {
        if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
            return *(it + dist);
        }
    }

    return null;
}

} // namespace entt

#endif
<commit_msg>helper: use the right page size in all cases<commit_after>#ifndef ENTT_ENTITY_HELPER_HPP
#define ENTT_ENTITY_HELPER_HPP

#include <type_traits>
#include "../core/fwd.hpp"
#include "../core/type_traits.hpp"
#include "../signal/delegate.hpp"
#include "component.hpp"
#include "fwd.hpp"
#include "registry.hpp"

namespace entt {

/**
 * @brief Converts a registry to a view.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct as_view {
    /*! @brief Underlying entity identifier. */
    using entity_type = std::remove_const_t<Entity>;
    /*! @brief Type of registry to convert. */
    using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;

    /**
     * @brief Constructs a converter for a given registry.
     * @param source A valid reference to a registry.
     */
    as_view(registry_type &source) noexcept
        : reg{source} {}

    /**
     * @brief Conversion function from a registry to a view.
     * @tparam Exclude Types of components used to filter the view.
     * @tparam Component Type of components used to construct the view.
     * @return A newly created view.
     */
    template<typename Exclude, typename... Component>
    operator basic_view<entity_type, get_t<Component...>, Exclude>() const {
        return reg.template view<Component...>(Exclude{});
    }

private:
    registry_type ®
};

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_view(basic_registry<Entity> &) -> as_view<Entity>;

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_view(const basic_registry<Entity> &) -> as_view<const Entity>;

/**
 * @brief Converts a registry to a group.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
struct as_group {
    /*! @brief Underlying entity identifier. */
    using entity_type = std::remove_const_t<Entity>;
    /*! @brief Type of registry to convert. */
    using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;

    /**
     * @brief Constructs a converter for a given registry.
     * @param source A valid reference to a registry.
     */
    as_group(registry_type &source) noexcept
        : reg{source} {}

    /**
     * @brief Conversion function from a registry to a group.
     * @tparam Get Types of components observed by the group.
     * @tparam Exclude Types of components used to filter the group.
     * @tparam Owned Types of components owned by the group.
     * @return A newly created group.
     */
    template<typename Get, typename Exclude, typename... Owned>
    operator basic_group<entity_type, owned_t<Owned...>, Get, Exclude>() const {
        if constexpr(std::is_const_v<registry_type>) {
            return reg.template group_if_exists<Owned...>(Get{}, Exclude{});
        } else {
            return reg.template group<Owned...>(Get{}, Exclude{});
        }
    }

private:
    registry_type ®
};

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_group(basic_registry<Entity> &) -> as_group<Entity>;

/**
 * @brief Deduction guide.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 */
template<typename Entity>
as_group(const basic_registry<Entity> &) -> as_group<const Entity>;

/**
 * @brief Helper to create a listener that directly invokes a member function.
 * @tparam Member Member function to invoke on a component of the given type.
 * @tparam Entity A valid entity type (see entt_traits for more details).
 * @param reg A registry that contains the given entity and its components.
 * @param entt Entity from which to get the component.
 */
template<auto Member, typename Entity = entity>
void invoke(basic_registry<Entity> &reg, const Entity entt) {
    static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
    delegate<void(basic_registry<Entity> &, const Entity)> func;
    func.template connect<Member>(reg.template get<member_class_t<decltype(Member)>>(entt));
    func(reg, entt);
}

/**
 * @brief Returns the entity associated with a given component.
 *
 * @warning
 * Currently, this function only works correctly with the default pool as it
 * makes assumptions about how the components are laid out.
 *
 * @tparam Entity A valid entity type (see entt_traits for more details).
 * @tparam Component Type of component.
 * @param reg A registry that contains the given entity and its components.
 * @param instance A valid component instance.
 * @return The entity associated with the given component.
 */
template<typename Entity, typename Component>
Entity to_entity(const basic_registry<Entity> &reg, const Component &instance) {
    const auto &storage = reg.template storage<Component>();
    const typename basic_registry<Entity>::base_type &base = storage;
    const auto *addr = std::addressof(instance);

    for(auto it = base.rbegin(), last = base.rend(); it < last; it += component_traits<Component>::page_size) {
        if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < component_traits<Component>::page_size) {
            return *(it + dist);
        }
    }

    return null;
}

} // namespace entt

#endif
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Karoliina T. Salminen <karoliina.t.salminen@nokia.com>
**
** This file is part of duicontrolpanel.
**
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QObject>
#include <QByteArray>

#include <DcpApplet>
#include <DcpWidgetTypes>

#include <dcpappletmetadata.h>
#include <dcpappletmetadata_p.h>

#include "ut_dcpappletmetadata.h"
#include "filedatas.h"
#include "dcpmostusedcounter.h"

void Ut_DcpAppletMetadata::initTestCase()
{
    static int c = 0;
    static QByteArray arg("dummyarg");
    char *argp = arg.data();
    qap = new QCoreApplication(c, &argp);
    QString desktopDir(qApp->applicationDirPath() +
                       "/ut_dcpappletmetadata-data/desktops/");
    desktopTestFile =  desktopDir + "test.desktop";
    desktopBadTestFile = desktopDir + "testBad.desktop";

    appletDir = "so.applet/";
    appletSo = "testapplet.so";
    fileDatas[desktopTestFile]["Name"] = "Browser";
    fileDatas[desktopTestFile]["Desktop Entry/Type"] = "DUIApplet";
    fileDatas[desktopTestFile]["Desktop Entry/Icon"] = "";
    fileDatas[desktopTestFile]["Desktop Entry/Exec"] = "";
    fileDatas[desktopTestFile]["Desktop Entry/X-logical-id"] = "qtn_sett_main_browser";
    fileDatas[desktopTestFile]["Desktop Entry/X-translation-catalog"] = "duisettings1,duisettings2";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-Applet"] = "testapplet.so";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet/ImageLandscape"] = "Widget_landscape_weather.png";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ImagePortrait"] = "Widget_portrait_weather.png";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ApplicationCommand"] = "./test";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-Dslfile"] = "dslfile";
    fileDatas[desktopTestFile]["DCP/Category"] = "Application";
    fileDatas[desktopTestFile]["DCP/Order"] = "1";
    fileDatas[desktopTestFile]["DCP/HelpId"] = "helpid";
    fileDatas[desktopTestFile]["DCP/WidgetType"] = "DcpLabel2";
    fileDatas[desktopTestFile]["DCP/Text2"] = "firefox";
    fileDatas[desktopTestFile]["DCP/Align"] = "RIGHT";
    fileDatas[desktopTestFile]["DCP/Image"] = "test.png";
    fileDatas[desktopTestFile]["DCP/Part"] = "RobiJonMegKutyaraDer";
    fileDatas[desktopTestFile]["DCP/Parent"] = "RobiJonMegKutyaraDer_II";
    fileDatas[desktopTestFile]["isValid"] = "y";
    fileDatas[desktopBadTestFile]["Desktop Entry/Name"] = "Browser";
    fileDatas[desktopBadTestFile]["Desktop Entry/Type"] = "DUIApplet";
    fileDatas[desktopBadTestFile]["Desktop Entry/Icon"] = "";
    fileDatas[desktopBadTestFile]["Desktop Entry/Exec"] = "";
    fileDatas[desktopBadTestFile]["Desktop Entry/X-logical-id"] = "qtn_sett_main_browser";
    fileDatas[desktopBadTestFile]["Desktop Entry/X-translation-catalog"] = "duisettings";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet-Applet"] = "libexampleapplet.so";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet/ImageLandscape"] = "Widget_landscape_weather.png";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet-ImagePortrait"] = "Widget_portrait_weather.png";
    fileDatas[desktopBadTestFile]["DCP/Category"] = "Application";
    fileDatas[desktopBadTestFile]["DCP/Order"] = "1";
    fileDatas[desktopBadTestFile]["DCP/WidgetType"] = "DcpLabel2";
    fileDatas[desktopBadTestFile]["DCP/Text2"] = "firefox";
    fileDatas[desktopBadTestFile]["isValid"] = "n";

}

void Ut_DcpAppletMetadata::cleanupTestCase()
{
    delete qap;
}

void Ut_DcpAppletMetadata::init()
{
    QVERIFY(m_subject = new DcpAppletMetadata(desktopTestFile));
}

void Ut_DcpAppletMetadata::cleanup()
{
    if (m_subject) {
       delete m_subject;
       m_subject = 0;
    }
}

void Ut_DcpAppletMetadata::testCreateAndDestroy()
{
    if (QTest::currentTestFailed()) return;
}

void Ut_DcpAppletMetadata::testIsValid()
{
    if (QTest::currentTestFailed()) return;

    QVERIFY(m_subject->isValid());
    delete m_subject;
    m_subject = 0;

    QWARN("\n\t----Expected QWARN: Multiple definitions of group 'M'----");
    QVERIFY((m_subject = new DcpAppletMetadata(desktopBadTestFile)));
    QVERIFY(!m_subject->isValid());
}

void Ut_DcpAppletMetadata::testIsModified()
{
    if (QTest::currentTestFailed()) return;

    QVERIFY((m_subject = new DcpAppletMetadata(desktopTestFile)));

    QVERIFY(!m_subject->isModified());

#if 0
    FIXME

    // touch the desktop file:
    QFile file(desktopTestFile);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    file.close();

    QVERIFY(m_subject->isModified());
#endif
}

void Ut_DcpAppletMetadata::testName()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->name(), QString("Browser"));
}
void Ut_DcpAppletMetadata::testFileName()
{
    if (QTest::currentTestFailed()) return;
    QVERIFY((m_subject = new DcpAppletMetadata(desktopTestFile)));

    QCOMPARE(m_subject->fileName(), desktopTestFile);
}

void Ut_DcpAppletMetadata::testCategory()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->category(), QString("Application"));
}

void Ut_DcpAppletMetadata::testBinary()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->binary(), QString("testapplet.so"));
}

void Ut_DcpAppletMetadata::testFullBinary()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->fullBinary(), appletDir + appletSo);
}

void Ut_DcpAppletMetadata::testWidgetTypeID()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->widgetTypeID(), static_cast<int>(DcpWidgetType::Label));
}

void Ut_DcpAppletMetadata::testAlign()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->align(), Qt::AlignRight);

}

void Ut_DcpAppletMetadata::testToggle()
{
    m_subject->toggle();
}

void Ut_DcpAppletMetadata::testImageName()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->imageName(), QString("test.png"));
}

void Ut_DcpAppletMetadata::testOrder()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->order(), 1);
}

#ifdef MOSTUSED
void Ut_DcpAppletMetadata::testUsage()
{
    QSKIP("!!!! RelativePath bug under fixxing by Retsoft !!!!", SkipSingle);

/*
    if (QTest::currentTestFailed()) return;

    qWarning() <<"\n@@" <<m_subject->usage() <<"@@\n";
 */
}

void Ut_DcpAppletMetadata::testUsageGreatherThan()
{
    DcpAppletMetadata *metadata = new DcpAppletMetadata(desktopBadTestFile);
    MostUsedCounter::instance()->incrementUsageCount (
            QFileInfo(desktopTestFile).baseName()
    );
    QVERIFY(DcpAppletMetadata::usageGreatherThan(m_subject, metadata));
    delete metadata;
}
#endif

void Ut_DcpAppletMetadata::testPart()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->part(), QString("RobiJonMegKutyaraDer"));
}

void Ut_DcpAppletMetadata::testHelpId()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->helpId(), QString("helpid"));
}

void Ut_DcpAppletMetadata::testDslFilename()
{
    if (QTest::currentTestFailed()) return;
    QCOMPARE(m_subject->dslFilename(), QString("dslfile"));
}

void Ut_DcpAppletMetadata::testApplicationCommand()
{
    if (QTest::currentTestFailed()) return;
    QVERIFY(m_subject->hasApplicationCommand());
    QCOMPARE(m_subject->applicationCommand(), QString("./test"));
    delete m_subject;
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ApplicationCommand"] = "";
    m_subject = new DcpAppletMetadata(desktopTestFile);
    QVERIFY(!m_subject->hasApplicationCommand());
}

void Ut_DcpAppletMetadata::testTranslationCatalog()
{
    if (QTest::currentTestFailed()) return;
    QStringList expected;
    expected << "duisettings1" << "duisettings2";
    QCOMPARE(m_subject->translationCatalogs(), expected);
}

void Ut_DcpAppletMetadata::testText2()
{
    if (QTest::currentTestFailed()) return;
    QCOMPARE(m_subject->text2(), QString("!! firefox"));
    m_subject->d_ptr->m_Disabled = true;
    QCOMPARE(m_subject->text2(), QString("Disabled"));
}

void Ut_DcpAppletMetadata::testIncrementUsage()
{
    if (QTest::currentTestFailed()) return;
    QSKIP("remove if finished", SkipSingle);
}

void Ut_DcpAppletMetadata::testDisabled()
{
    m_subject->d_ptr->m_Disabled = false;
    QVERIFY(!m_subject->isDisabled());
    m_subject->setDisabled(true);
    QVERIFY(m_subject->d_ptr->m_Disabled);
}

void Ut_DcpAppletMetadata::testOrderLessThan()
{
    fileDatas[desktopTestFile]["DCP/Order"] = "100";
    DcpAppletMetadata *metadata = new DcpAppletMetadata(desktopTestFile);
    QVERIFY(DcpAppletMetadata::orderLessThan(m_subject, metadata));
    delete metadata;
}

void Ut_DcpAppletMetadata::testActive()
{
    if (QTest::currentTestFailed()) return;
    m_subject->d_ptr->m_Activated = 0;
    QVERIFY(!m_subject->isActive());
    m_subject->markActive();
    m_subject->markActive();
    QVERIFY(m_subject->isActive());
    m_subject->markInactive();
    QVERIFY(m_subject->isActive());
    m_subject->markInactive();
    QVERIFY(!m_subject->isActive());
}

void Ut_DcpAppletMetadata::testDefaultSOPath()
{
    m_subject->setDefaultSOPath("subidubi");
    QCOMPARE(m_subject->defaultSOPath(), QString("subidubi/"));
}

void Ut_DcpAppletMetadata::testTextOrientation()
{
    QCOMPARE(m_subject->textOrientation(), Qt::Vertical);
}

void Ut_DcpAppletMetadata::testText1()
{
    QCOMPARE(m_subject->text1(), QString("!! "));
}

void Ut_DcpAppletMetadata::testToggleIconId()
{
    QCOMPARE(m_subject->toggleIconId(), QString());
}

void Ut_DcpAppletMetadata::testIsUnique()
{
    QCOMPARE(m_subject->isUnique(), false);
}

void Ut_DcpAppletMetadata::testLessThans()
{
    QCOMPARE(m_subject->nameLessThan(m_subject, m_subject), false);
    QCOMPARE(m_subject->titleLessThan(m_subject, m_subject), false);
    QCOMPARE(m_subject->usageGreatherThan(m_subject, m_subject), false);
}
void Ut_DcpAppletMetadata::testUseless()
{
    m_subject->usage();
    m_subject->incrementUsage();
    QCOMPARE((void*)m_subject->lastUsed(), (void*)DcpAppletMetadataPrivate::sm_LastUsed);
    m_subject->setLastUsed(m_subject);
    QCOMPARE((void*)DcpAppletMetadataPrivate::sm_LastUsed, (void*)m_subject);
    m_subject->storedLastUsedItem();
    QCOMPARE(m_subject->isHidden(), false);
    QCOMPARE(m_subject->hasMainView(), true);
    QCOMPARE(m_subject->sliderLeftImage(), QString());
    QCOMPARE(m_subject->sliderRightImage(), QString());
    QCOMPARE(m_subject->hasInProcessBrief(), false);

}

QTEST_APPLESS_MAIN(Ut_DcpAppletMetadata)
<commit_msg>A unittest fix for last commit<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Karoliina T. Salminen <karoliina.t.salminen@nokia.com>
**
** This file is part of duicontrolpanel.
**
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QObject>
#include <QByteArray>

#include <DcpApplet>
#include <DcpWidgetTypes>

#include <dcpappletmetadata.h>
#include <dcpappletmetadata_p.h>

#include "ut_dcpappletmetadata.h"
#include "filedatas.h"
#include "dcpmostusedcounter.h"

void Ut_DcpAppletMetadata::initTestCase()
{
    static int c = 0;
    static QByteArray arg("dummyarg");
    char *argp = arg.data();
    qap = new QCoreApplication(c, &argp);
    QString desktopDir(qApp->applicationDirPath() +
                       "/ut_dcpappletmetadata-data/desktops/");
    desktopTestFile =  desktopDir + "test.desktop";
    desktopBadTestFile = desktopDir + "testBad.desktop";

    appletDir = "so.applet/";
    appletSo = "testapplet.so";
    fileDatas[desktopTestFile]["Name"] = "Browser";
    fileDatas[desktopTestFile]["Desktop Entry/Type"] = "DUIApplet";
    fileDatas[desktopTestFile]["Desktop Entry/Icon"] = "";
    fileDatas[desktopTestFile]["Desktop Entry/Exec"] = "";
    fileDatas[desktopTestFile]["Desktop Entry/X-logical-id"] = "qtn_sett_main_browser";
    fileDatas[desktopTestFile]["Desktop Entry/X-translation-catalog"] = "duisettings1,duisettings2";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-Applet"] = "testapplet.so";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet/ImageLandscape"] = "Widget_landscape_weather.png";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ImagePortrait"] = "Widget_portrait_weather.png";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ApplicationCommand"] = "./test";
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-Dslfile"] = "dslfile";
    fileDatas[desktopTestFile]["DCP/Category"] = "Application";
    fileDatas[desktopTestFile]["DCP/Order"] = "1";
    fileDatas[desktopTestFile]["DCP/HelpId"] = "helpid";
    fileDatas[desktopTestFile]["DCP/WidgetType"] = "DcpLabel2";
    fileDatas[desktopTestFile]["DCP/Text2"] = "firefox";
    fileDatas[desktopTestFile]["DCP/Align"] = "RIGHT";
    fileDatas[desktopTestFile]["DCP/Image"] = "test.png";
    fileDatas[desktopTestFile]["DCP/Part"] = "RobiJonMegKutyaraDer";
    fileDatas[desktopTestFile]["DCP/Parent"] = "RobiJonMegKutyaraDer_II";
    fileDatas[desktopTestFile]["isValid"] = "y";
    fileDatas[desktopBadTestFile]["Desktop Entry/Name"] = "Browser";
    fileDatas[desktopBadTestFile]["Desktop Entry/Type"] = "DUIApplet";
    fileDatas[desktopBadTestFile]["Desktop Entry/Icon"] = "";
    fileDatas[desktopBadTestFile]["Desktop Entry/Exec"] = "";
    fileDatas[desktopBadTestFile]["Desktop Entry/X-logical-id"] = "qtn_sett_main_browser";
    fileDatas[desktopBadTestFile]["Desktop Entry/X-translation-catalog"] = "duisettings";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet-Applet"] = "libexampleapplet.so";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet/ImageLandscape"] = "Widget_landscape_weather.png";
    fileDatas[desktopBadTestFile]["DUI/X-DUIApplet-ImagePortrait"] = "Widget_portrait_weather.png";
    fileDatas[desktopBadTestFile]["DCP/Category"] = "Application";
    fileDatas[desktopBadTestFile]["DCP/Order"] = "1";
    fileDatas[desktopBadTestFile]["DCP/WidgetType"] = "DcpLabel2";
    fileDatas[desktopBadTestFile]["DCP/Text2"] = "firefox";
    fileDatas[desktopBadTestFile]["isValid"] = "n";

}

void Ut_DcpAppletMetadata::cleanupTestCase()
{
    delete qap;
}

void Ut_DcpAppletMetadata::init()
{
    QVERIFY(m_subject = new DcpAppletMetadata(desktopTestFile));
}

void Ut_DcpAppletMetadata::cleanup()
{
    if (m_subject) {
       delete m_subject;
       m_subject = 0;
    }
}

void Ut_DcpAppletMetadata::testCreateAndDestroy()
{
    if (QTest::currentTestFailed()) return;
}

void Ut_DcpAppletMetadata::testIsValid()
{
    if (QTest::currentTestFailed()) return;

    QVERIFY(m_subject->isValid());
    delete m_subject;
    m_subject = 0;

    QWARN("\n\t----Expected QWARN: Multiple definitions of group 'M'----");
    QVERIFY((m_subject = new DcpAppletMetadata(desktopBadTestFile)));
    QVERIFY(!m_subject->isValid());
}

void Ut_DcpAppletMetadata::testIsModified()
{
    if (QTest::currentTestFailed()) return;

    QVERIFY((m_subject = new DcpAppletMetadata(desktopTestFile)));

    QVERIFY(!m_subject->isModified());

#if 0
    FIXME

    // touch the desktop file:
    QFile file(desktopTestFile);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    file.close();

    QVERIFY(m_subject->isModified());
#endif
}

void Ut_DcpAppletMetadata::testName()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->name(), QString("Browser"));
}
void Ut_DcpAppletMetadata::testFileName()
{
    if (QTest::currentTestFailed()) return;
    QVERIFY((m_subject = new DcpAppletMetadata(desktopTestFile)));

    QCOMPARE(m_subject->fileName(), desktopTestFile);
}

void Ut_DcpAppletMetadata::testCategory()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->category(), QString("Application"));
}

void Ut_DcpAppletMetadata::testBinary()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->binary(), QString("testapplet.so"));
}

void Ut_DcpAppletMetadata::testFullBinary()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->fullBinary(), appletDir + appletSo);
}

void Ut_DcpAppletMetadata::testWidgetTypeID()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->widgetTypeID(), static_cast<int>(DcpWidgetType::Label));
}

void Ut_DcpAppletMetadata::testAlign()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->align(), Qt::AlignRight);

}

void Ut_DcpAppletMetadata::testToggle()
{
    m_subject->toggle();
}

void Ut_DcpAppletMetadata::testImageName()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->imageName(), QString("test.png"));
}

void Ut_DcpAppletMetadata::testOrder()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->order(), 1);
}

#ifdef MOSTUSED
void Ut_DcpAppletMetadata::testUsage()
{
    QSKIP("!!!! RelativePath bug under fixxing by Retsoft !!!!", SkipSingle);

/*
    if (QTest::currentTestFailed()) return;

    qWarning() <<"\n@@" <<m_subject->usage() <<"@@\n";
 */
}

void Ut_DcpAppletMetadata::testUsageGreatherThan()
{
    DcpAppletMetadata *metadata = new DcpAppletMetadata(desktopBadTestFile);
    MostUsedCounter::instance()->incrementUsageCount (
            QFileInfo(desktopTestFile).baseName()
    );
    QVERIFY(DcpAppletMetadata::usageGreatherThan(m_subject, metadata));
    delete metadata;
}
#endif

void Ut_DcpAppletMetadata::testPart()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->part(), QString("RobiJonMegKutyaraDer"));
}

void Ut_DcpAppletMetadata::testHelpId()
{
    if (QTest::currentTestFailed()) return;

    QCOMPARE(m_subject->helpId(), QString("helpid"));
}

void Ut_DcpAppletMetadata::testDslFilename()
{
    if (QTest::currentTestFailed()) return;
    QCOMPARE(m_subject->dslFilename(), QString("dslfile"));
}

void Ut_DcpAppletMetadata::testApplicationCommand()
{
    if (QTest::currentTestFailed()) return;
    QVERIFY(m_subject->hasApplicationCommand());
    QCOMPARE(m_subject->applicationCommand(), QString("./test"));
    delete m_subject;
    fileDatas[desktopTestFile]["DUI/X-DUIApplet-ApplicationCommand"] = "";
    m_subject = new DcpAppletMetadata(desktopTestFile);
    QVERIFY(!m_subject->hasApplicationCommand());
}

void Ut_DcpAppletMetadata::testTranslationCatalog()
{
    if (QTest::currentTestFailed()) return;
    QStringList expected;
    expected << "duisettings1" << "duisettings2";
    QCOMPARE(m_subject->translationCatalogs(), expected);
}

void Ut_DcpAppletMetadata::testText2()
{
    if (QTest::currentTestFailed()) return;
    QCOMPARE(m_subject->text2(), QString("firefox"));
    m_subject->d_ptr->m_Disabled = true;
    QCOMPARE(m_subject->text2(), QString("Disabled"));
}

void Ut_DcpAppletMetadata::testIncrementUsage()
{
    if (QTest::currentTestFailed()) return;
    QSKIP("remove if finished", SkipSingle);
}

void Ut_DcpAppletMetadata::testDisabled()
{
    m_subject->d_ptr->m_Disabled = false;
    QVERIFY(!m_subject->isDisabled());
    m_subject->setDisabled(true);
    QVERIFY(m_subject->d_ptr->m_Disabled);
}

void Ut_DcpAppletMetadata::testOrderLessThan()
{
    fileDatas[desktopTestFile]["DCP/Order"] = "100";
    DcpAppletMetadata *metadata = new DcpAppletMetadata(desktopTestFile);
    QVERIFY(DcpAppletMetadata::orderLessThan(m_subject, metadata));
    delete metadata;
}

void Ut_DcpAppletMetadata::testActive()
{
    if (QTest::currentTestFailed()) return;
    m_subject->d_ptr->m_Activated = 0;
    QVERIFY(!m_subject->isActive());
    m_subject->markActive();
    m_subject->markActive();
    QVERIFY(m_subject->isActive());
    m_subject->markInactive();
    QVERIFY(m_subject->isActive());
    m_subject->markInactive();
    QVERIFY(!m_subject->isActive());
}

void Ut_DcpAppletMetadata::testDefaultSOPath()
{
    m_subject->setDefaultSOPath("subidubi");
    QCOMPARE(m_subject->defaultSOPath(), QString("subidubi/"));
}

void Ut_DcpAppletMetadata::testTextOrientation()
{
    QCOMPARE(m_subject->textOrientation(), Qt::Vertical);
}

void Ut_DcpAppletMetadata::testText1()
{
    QCOMPARE(m_subject->text1(), QString(""));
}

void Ut_DcpAppletMetadata::testToggleIconId()
{
    QCOMPARE(m_subject->toggleIconId(), QString());
}

void Ut_DcpAppletMetadata::testIsUnique()
{
    QCOMPARE(m_subject->isUnique(), false);
}

void Ut_DcpAppletMetadata::testLessThans()
{
    QCOMPARE(m_subject->nameLessThan(m_subject, m_subject), false);
    QCOMPARE(m_subject->titleLessThan(m_subject, m_subject), false);
    QCOMPARE(m_subject->usageGreatherThan(m_subject, m_subject), false);
}
void Ut_DcpAppletMetadata::testUseless()
{
    m_subject->usage();
    m_subject->incrementUsage();
    QCOMPARE((void*)m_subject->lastUsed(), (void*)DcpAppletMetadataPrivate::sm_LastUsed);
    m_subject->setLastUsed(m_subject);
    QCOMPARE((void*)DcpAppletMetadataPrivate::sm_LastUsed, (void*)m_subject);
    m_subject->storedLastUsedItem();
    QCOMPARE(m_subject->isHidden(), false);
    QCOMPARE(m_subject->hasMainView(), true);
    QCOMPARE(m_subject->sliderLeftImage(), QString());
    QCOMPARE(m_subject->sliderRightImage(), QString());
    QCOMPARE(m_subject->hasInProcessBrief(), false);

}

QTEST_APPLESS_MAIN(Ut_DcpAppletMetadata)
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A>
struct bias_batch_mean_expr : base_temporary_expr_un<bias_batch_mean_expr<A>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_expr<A>;                    ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_expr(A a) : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C, cpp_enable_if(all_fast<A,C>::value)>
    static void check(const A& a, const C& c) {
        cpp_unused(a);
        cpp_unused(c);

        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean is a 4D matrix");

        static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean");
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C, cpp_disable_if(all_fast<A,C>::value)>
    static void check(const A& a, const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean is a 4D matrix");

        cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean");

        cpp_unused(a);
        cpp_unused(c);
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) = mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_add_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) += mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_sub_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) -= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mul_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) *= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_div_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) /= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template<typename L>
    void assign_mod_to(L&& lhs)  const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) %= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_expr& expr) {
        return os << "bias_batch_mean(" << expr._a << ")";
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A>
struct etl_traits<etl::bias_batch_mean_expr<A>> {
    using expr_t     = etl::bias_batch_mean_expr<A>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;              ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;       ///< The sub traits
    using value_type = value_t<A>;                   ///< The value type of the expression

    static constexpr bool is_etl                  = true;                      ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer          = false;                     ///< Indicates if the type is a transformer
    static constexpr bool is_view                 = false;                     ///< Indicates if the type is a view
    static constexpr bool is_magic_view           = false;                     ///< Indicates if the type is a magic view
    static constexpr bool is_fast                 = sub_traits::is_fast;       ///< Indicates if the expression is fast
    static constexpr bool is_linear               = true;                      ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe          = true;                      ///< Indicates if the expression is thread safe
    static constexpr bool is_value                = false;                     ///< Indicates if the expression is of value type
    static constexpr bool is_direct               = true;                      ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator            = false;                     ///< Indicates if the expression is a generator
    static constexpr bool is_padded               = false;                     ///< Indicates if the expression is padded
    static constexpr bool is_aligned              = true;                      ///< Indicates if the expression is padded
    static constexpr bool is_gpu                  = false;                     ///< Indicates if the expression can be done on GPU
    static constexpr bool is_temporary = true;                      ///< Indicates if the expression needs a evaluator visitor
    static constexpr order storage_order          = sub_traits::storage_order; ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    using vectorizable = std::true_type;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");
        cpp_unused(d);
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_expr<detail::build_type<E>> bias_batch_mean(const E& value) {
    static_assert(is_etl_expr<E>::value, "etl::bias_batch_mean can only be used on ETL expressions");
    static_assert(decay_traits<E>::dimensions() == 4, "etl::bias_batch_mean is only defined for 4D input");

    return bias_batch_mean_expr<detail::build_type<E>>{value};
}

} //end of namespace etl
<commit_msg>Cleanup code style<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A>
struct bias_batch_mean_expr : base_temporary_expr_un<bias_batch_mean_expr<A>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_expr<A>;              ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_expr(A a)
            : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C, cpp_enable_if(all_fast<A, C>::value)>
    static void check(const A& a, const C& c) {
        cpp_unused(a);
        cpp_unused(c);

        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean is a 4D matrix");

        static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean");
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C, cpp_disable_if(all_fast<A, C>::value)>
    static void check(const A& a, const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean is a 4D matrix");

        cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean");

        cpp_unused(a);
        cpp_unused(c);
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) = mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_add_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) += mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_sub_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) -= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mul_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) *= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_div_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) /= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mod_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>::value, "bias_batch_mean only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            if (last - first) {
                SERIAL_SECTION {
                    for (size_t k = first; k < last; ++k) {
                        T mean(0);

                        for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                            mean += sum(a(b)(k));
                        }

                        lhs(k) %= mean / N;
                    }
                }
            }
        };

        engine_dispatch_1d(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_expr& expr) {
        return os << "bias_batch_mean(" << expr._a << ")";
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A>
struct etl_traits<etl::bias_batch_mean_expr<A>> {
    using expr_t     = etl::bias_batch_mean_expr<A>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;              ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;       ///< The sub traits
    using value_type = value_t<A>;                   ///< The value type of the expression

    static constexpr bool is_etl         = true;                      ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer = false;                     ///< Indicates if the type is a transformer
    static constexpr bool is_view        = false;                     ///< Indicates if the type is a view
    static constexpr bool is_magic_view  = false;                     ///< Indicates if the type is a magic view
    static constexpr bool is_fast        = sub_traits::is_fast;       ///< Indicates if the expression is fast
    static constexpr bool is_linear      = true;                      ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe = true;                      ///< Indicates if the expression is thread safe
    static constexpr bool is_value       = false;                     ///< Indicates if the expression is of value type
    static constexpr bool is_direct      = true;                      ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator   = false;                     ///< Indicates if the expression is a generator
    static constexpr bool is_padded      = false;                     ///< Indicates if the expression is padded
    static constexpr bool is_aligned     = true;                      ///< Indicates if the expression is padded
    static constexpr bool is_gpu         = false;                     ///< Indicates if the expression can be done on GPU
    static constexpr bool is_temporary   = true;                      ///< Indicates if the expression needs a evaluator visitor
    static constexpr order storage_order = sub_traits::storage_order; ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    using vectorizable = std::true_type;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");
        cpp_unused(d);
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_expr<detail::build_type<E>> bias_batch_mean(const E& value) {
    static_assert(is_etl_expr<E>::value, "etl::bias_batch_mean can only be used on ETL expressions");
    static_assert(decay_traits<E>::dimensions() == 4, "etl::bias_batch_mean is only defined for 4D input");

    return bias_batch_mean_expr<detail::build_type<E>>{value};
}

} //end of namespace etl
<|endoftext|>


<commit_before><commit_msg>Force #defined constants to sal_uInt32 to reduce conversion warnings<commit_after><|endoftext|>


<commit_before>//
//  Logarithm.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "Logarithm.h"

Logarithm::Logarithm(int base, int operand){
    this->base = base;
    this->operand = operand;
}
Logarithm::~Logarithm(){

}
Expression Logarithm::simplify(){
    Expression* c = this;
    return *c;
}

Expression* Logarithm::add(Expression* a, Expression* b){
    Expression* c = this;
    return c;
}
Expression* Logarithm::subtract(Expression* a, Expression* b){
    Expression* c = this;
    return c;
}
Expression* Logarithm::multiply(Expression* a, Expression* b){
    Expression* c = this;
    return c;
}
Expression* Logarithm::divide(Expression* a, Expression* b){
    Expression* c = this;
    return c;
}
<commit_msg>Added virtual print function<commit_after>//
//  Logarithm.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "Logarithm.h"

Logarithm::Logarithm(int base, int operand){
    this->type = "logarithm";
    this->base = base;
    this->operand = operand;
}
Logarithm::~Logarithm(){

}
Expression Logarithm::simplify(){
    Expression* c = this;
    return *c;
}

Expression* Logarithm::add(Expression* a){
    Expression* c = this;
    return c;
}
Expression* Logarithm::subtract(Expression* a){
    Expression* c = this;
    return c;
}
Expression* Logarithm::multiply(Expression* a){
    Expression* c = this;
    return c;
}
Expression* Logarithm::divide(Expression* a){
    Expression* c = this;
    return c;
}
ostream& Logarithm::print(std::ostream& output) const{
    output << "Log" << this->base << "(" << this->operand << ")";
    return output;
}
<|endoftext|>


<commit_before>// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/common/cpp/client_wrapper/testing/encodable_value_utils.h"

#include <cmath>

namespace flutter {
namespace testing {

bool EncodableValuesAreEqual(const EncodableValue& a, const EncodableValue& b) {
  if (a.type() != b.type()) {
    return false;
  }

  switch (a.type()) {
    case EncodableValue::Type::kNull:
      return true;
    case EncodableValue::Type::kBool:
      return a.BoolValue() == b.BoolValue();
    case EncodableValue::Type::kInt:
      return a.IntValue() == b.IntValue();
    case EncodableValue::Type::kLong:
      return a.LongValue() == b.LongValue();
    case EncodableValue::Type::kDouble:
      // This is a crude epsilon, but fine for the values in the the unit tests.
      return std::abs(a.DoubleValue() - b.DoubleValue()) < 0.0001l;
    case EncodableValue::Type::kString:
      return a.StringValue() == b.StringValue();
    case EncodableValue::Type::kByteList:
      return a.ByteListValue() == b.ByteListValue();
    case EncodableValue::Type::kIntList:
      return a.IntListValue() == b.IntListValue();
    case EncodableValue::Type::kLongList:
      return a.LongListValue() == b.LongListValue();
    case EncodableValue::Type::kDoubleList:
      return a.DoubleListValue() == b.DoubleListValue();
    case EncodableValue::Type::kList: {
      const auto& a_list = a.ListValue();
      const auto& b_list = b.ListValue();
      if (a_list.size() != b_list.size()) {
        return false;
      }
      for (size_t i = 0; i < a_list.size(); ++i) {
        if (!EncodableValuesAreEqual(a_list[0], b_list[0])) {
          return false;
        }
      }
      return true;
    }
    case EncodableValue::Type::kMap: {
      const auto& a_map = a.MapValue();
      const auto& b_map = b.MapValue();
      if (a_map.size() != b_map.size()) {
        return false;
      }
      // Store references to all the keys in |b|.
      std::vector<const EncodableValue*> unmatched_b_keys;
      for (auto& pair : b_map) {
        unmatched_b_keys.push_back(&pair.first);
      }
      // For each key,value in |a|, see if any of the not-yet-matched key,value
      // pairs in |b| match by value; if so, remove that match and continue.
      for (const auto& pair : a_map) {
        bool found_match = false;
        for (size_t i = 0; i < unmatched_b_keys.size(); ++i) {
          const EncodableValue& b_key = *unmatched_b_keys[i];
          if (EncodableValuesAreEqual(pair.first, b_key) &&
              EncodableValuesAreEqual(pair.second, b_map.at(b_key))) {
            found_match = true;
            unmatched_b_keys.erase(unmatched_b_keys.begin() + i);
            break;
          }
        }
        if (!found_match) {
          return false;
        }
      }
      // If all entries had matches, consider the maps equal.
      return true;
    }
  }
  assert(false);
  return false;
}

}  // namespace testing
}  // namespace flutter
<commit_msg>Fix typo in comment (#8617)<commit_after>// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/common/cpp/client_wrapper/testing/encodable_value_utils.h"

#include <cmath>

namespace flutter {
namespace testing {

bool EncodableValuesAreEqual(const EncodableValue& a, const EncodableValue& b) {
  if (a.type() != b.type()) {
    return false;
  }

  switch (a.type()) {
    case EncodableValue::Type::kNull:
      return true;
    case EncodableValue::Type::kBool:
      return a.BoolValue() == b.BoolValue();
    case EncodableValue::Type::kInt:
      return a.IntValue() == b.IntValue();
    case EncodableValue::Type::kLong:
      return a.LongValue() == b.LongValue();
    case EncodableValue::Type::kDouble:
      // This is a crude epsilon, but fine for the values in the unit tests.
      return std::abs(a.DoubleValue() - b.DoubleValue()) < 0.0001l;
    case EncodableValue::Type::kString:
      return a.StringValue() == b.StringValue();
    case EncodableValue::Type::kByteList:
      return a.ByteListValue() == b.ByteListValue();
    case EncodableValue::Type::kIntList:
      return a.IntListValue() == b.IntListValue();
    case EncodableValue::Type::kLongList:
      return a.LongListValue() == b.LongListValue();
    case EncodableValue::Type::kDoubleList:
      return a.DoubleListValue() == b.DoubleListValue();
    case EncodableValue::Type::kList: {
      const auto& a_list = a.ListValue();
      const auto& b_list = b.ListValue();
      if (a_list.size() != b_list.size()) {
        return false;
      }
      for (size_t i = 0; i < a_list.size(); ++i) {
        if (!EncodableValuesAreEqual(a_list[0], b_list[0])) {
          return false;
        }
      }
      return true;
    }
    case EncodableValue::Type::kMap: {
      const auto& a_map = a.MapValue();
      const auto& b_map = b.MapValue();
      if (a_map.size() != b_map.size()) {
        return false;
      }
      // Store references to all the keys in |b|.
      std::vector<const EncodableValue*> unmatched_b_keys;
      for (auto& pair : b_map) {
        unmatched_b_keys.push_back(&pair.first);
      }
      // For each key,value in |a|, see if any of the not-yet-matched key,value
      // pairs in |b| match by value; if so, remove that match and continue.
      for (const auto& pair : a_map) {
        bool found_match = false;
        for (size_t i = 0; i < unmatched_b_keys.size(); ++i) {
          const EncodableValue& b_key = *unmatched_b_keys[i];
          if (EncodableValuesAreEqual(pair.first, b_key) &&
              EncodableValuesAreEqual(pair.second, b_map.at(b_key))) {
            found_match = true;
            unmatched_b_keys.erase(unmatched_b_keys.begin() + i);
            break;
          }
        }
        if (!found_match) {
          return false;
        }
      }
      // If all entries had matches, consider the maps equal.
      return true;
    }
  }
  assert(false);
  return false;
}

}  // namespace testing
}  // namespace flutter
<|endoftext|>