<commit_before>// Copyright (c) 2014-2021 The Gridcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include "main.h"
#include "gridcoin/support/xml.h"
#include "gridcoin/voting/poll.h"
#include "span.h"
#include "ui_interface.h"
#include "util.h"

#include <boost/algorithm/string/join.hpp>

using namespace GRC;

namespace {
//!
//! \brief Parse the weight type from a legacy poll contract.
//!
//! \param value A numeric value extracted from the "<SHARETYPE>" field that
//! matches a value enumerated on \c PollWeightType.
//!
//! \return The matching weight type or the value of "unknown" when the string
//! does not contain a valid weight type number.
//!
PollWeightType ParseWeightType(const std::string& value)
{
    try {
        const uint32_t parsed = std::stoul(value);

        if (parsed > Poll::WeightType::MAX) {
            return PollWeightType::UNKNOWN;
        }

        return static_cast<PollWeightType>(parsed);
    } catch (...) {
        return PollWeightType::UNKNOWN;
    }
}

//!
//! \brief Parse the poll duration from a legacy poll contract.
//!
//! \param value A numeric value extracted from the "<DAYS>" field.
//!
//! \return The parsed number of days or zero when the string does not contain
//! a valid number.
//!
uint32_t ParseDurationDays(const std::string& value)
{
    try {
        return std::stoul(value);
    } catch (...) {
        return 0;
    }
}

//!
//! \brief Parse the set of available choices from a legacy poll contract.
//!
//! \param value A semicolon-delimited string of labels extracted from the
//! "<ANSWERS>" field. Each label represents one choice.
//!
//! \return The parsed set of poll choices.
//!
Poll::ChoiceList ParseChoices(const std::string& value)
{
    Poll::ChoiceList choices;

    for (auto& label : split(value, ";")) {
        choices.Add(std::move(label));
    }

    return choices;
}

//!
//! \brief Poll choices to return for polls with a yes/no/abstain response type.
//!
const Poll::ChoiceList g_yes_no_abstain_choices(std::vector<Poll::Choice> {
    { "Yes"     },
    { "No"      },
    { "Abstain" },
});
} // Anonymous namespace

// -----------------------------------------------------------------------------
// Class: Poll
// -----------------------------------------------------------------------------

Poll::Poll()
    : m_type(PollType::UNKNOWN)
    , m_weight_type(PollWeightType::UNKNOWN)
    , m_response_type(PollResponseType::UNKNOWN)
    , m_duration_days(0)
    , m_timestamp(0)
{
}

Poll::Poll(
    PollType type,
    PollWeightType weight_type,
    PollResponseType response_type,
    uint32_t duration_days,
    std::string title,
    std::string url,
    std::string question,
    ChoiceList choices,
    int64_t timestamp)
    : m_type(type)
    , m_weight_type(weight_type)
    , m_response_type(response_type)
    , m_duration_days(duration_days)
    , m_title(std::move(title))
    , m_url(std::move(url))
    , m_question(std::move(question))
    , m_choices(std::move(choices))
    , m_timestamp(timestamp)
{
}

Poll Poll::Parse(const std::string& title, const std::string& contract)
{
    return Poll(
        PollType::SURVEY,
        ParseWeightType(ExtractXML(contract, "<SHARETYPE>", "</SHARETYPE>")),
        // Legacy contracts only behaved as multiple-choice polls:
        PollResponseType::MULTIPLE_CHOICE,
        ParseDurationDays(ExtractXML(contract, "<DAYS>", "</DAYS>")),
        title,
        ExtractXML(contract, "<URL>", "</URL>"),
        ExtractXML(contract, "<QUESTION>", "</QUESTION>"),
        ParseChoices(ExtractXML(contract, "<ANSWERS>", "</ANSWERS>")),
        0);
}

bool Poll::WellFormed() const
{
    return m_type != PollType::UNKNOWN
        && m_type != PollType::OUT_OF_BOUND
        && m_weight_type != PollWeightType::UNKNOWN
        && m_weight_type != PollWeightType::OUT_OF_BOUND
        && m_response_type != PollResponseType::UNKNOWN
        && m_response_type != PollResponseType::OUT_OF_BOUND
        && m_duration_days >= MIN_DURATION_DAYS
        && m_duration_days <= MAX_DURATION_DAYS
        && !m_title.empty()
        && !m_url.empty()
        && m_choices.WellFormed(m_response_type.Value());
}

bool Poll::WellFormed(const uint32_t version) const
{
    if (!WellFormed()) {
        return false;
    }

    // Version 2+ poll contracts in block version 11 and greater disallow the
    // deprecated legacy vote weighing methods:
    //
    if (version >= 2) {
        switch (m_weight_type.Value()) {
            case PollWeightType::MAGNITUDE:
            case PollWeightType::CPID_COUNT:
            case PollWeightType::PARTICIPANT_COUNT:
                return false;
            default:
                break;
        }
    }

    return true;
}

bool Poll::IncludesMagnitudeWeight() const
{
    return m_weight_type == PollWeightType::BALANCE_AND_MAGNITUDE
        || m_weight_type == PollWeightType::MAGNITUDE;
}

bool Poll::AllowsMultipleChoices() const
{
    return m_response_type == PollResponseType::MULTIPLE_CHOICE;
}

int64_t Poll::Age(const int64_t now) const
{
    return now - m_timestamp;
}

bool Poll::Expired(const int64_t now) const
{
    return Age(now) > m_duration_days * 86400;
}

int64_t Poll::Expiration() const
{
    return m_timestamp + (m_duration_days * 86400);
}

const Poll::ChoiceList& Poll::Choices() const
{
    if (m_response_type == PollResponseType::YES_NO_ABSTAIN) {
        return g_yes_no_abstain_choices;
    }

    return m_choices;
}

std::string Poll::WeightTypeToString() const
{
    switch (m_weight_type.Value()) {
        case PollWeightType::UNKNOWN:
        case PollWeightType::OUT_OF_BOUND:          return _("Unknown");
        case PollWeightType::MAGNITUDE:             return _("Magnitude");
        case PollWeightType::BALANCE:               return _("Balance");
        case PollWeightType::BALANCE_AND_MAGNITUDE: return _("Magnitude+Balance");
        case PollWeightType::CPID_COUNT:            return _("CPID Count");
        case PollWeightType::PARTICIPANT_COUNT:     return _("Participant Count");
    }

    assert(false); // Suppress warning
}

std::string Poll::ResponseTypeToString() const
{
    switch (m_response_type.Value()) {
        case PollResponseType::UNKNOWN:
        case PollResponseType::OUT_OF_BOUND:    return _("Unknown");
        case PollResponseType::YES_NO_ABSTAIN:  return _("Yes/No/Abstain");
        case PollResponseType::SINGLE_CHOICE:   return _("Single Choice");
        case PollResponseType::MULTIPLE_CHOICE: return _("Multiple Choice");
    }

    assert(false); // Suppress warning
}

// -----------------------------------------------------------------------------
// Class: Poll::ChoiceList
// -----------------------------------------------------------------------------

using ChoiceList = Poll::ChoiceList;
using Choice = Poll::Choice;

ChoiceList::ChoiceList(std::vector<Choice> choices)
    : m_choices(std::move(choices))
{
}

ChoiceList::const_iterator ChoiceList::begin() const
{
    return m_choices.begin();
}

ChoiceList::const_iterator ChoiceList::end() const
{
    return m_choices.end();
}

size_t ChoiceList::size() const
{
    return m_choices.size();
}

bool ChoiceList::empty() const
{
    return m_choices.empty();
}

bool ChoiceList::WellFormed(const PollResponseType response_type) const
{
    if (response_type == PollResponseType::YES_NO_ABSTAIN) {
        return m_choices.empty();
    }

    return !m_choices.empty()
        && m_choices.size() <= POLL_MAX_CHOICES_SIZE
        && std::all_of(
            m_choices.begin(),
            m_choices.end(),
            [](const Choice& choice) { return choice.WellFormed(); });
}

bool ChoiceList::OffsetInRange(const size_t offset) const
{
    return offset < m_choices.size();
}

bool ChoiceList::LabelExists(const std::string& label) const
{
    return OffsetOf(label).operator bool();
}

std::optional<uint8_t> ChoiceList::OffsetOf(const std::string& label) const
{
    const auto iter = std::find_if(
        m_choices.begin(),
        m_choices.end(),
        [&](const Choice& choice) { return choice.m_label == label; });

    if (iter == m_choices.end()) {
        return std::nullopt;
    }

    return std::distance(m_choices.begin(), iter);
}

const Choice* ChoiceList::At(const size_t offset) const
{
    if (offset >= m_choices.size()) {
        return nullptr;
    }

    return &m_choices[offset];
}

void ChoiceList::Add(std::string label)
{
    m_choices.emplace_back(std::move(label));
}
<commit_msg>Change stoul to ParseUInt32 in poll.cpp<commit_after>// Copyright (c) 2014-2021 The Gridcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include "main.h"
#include "gridcoin/support/xml.h"
#include "gridcoin/voting/poll.h"
#include "span.h"
#include "ui_interface.h"
#include "util.h"

#include <boost/algorithm/string/join.hpp>

using namespace GRC;

namespace {
//!
//! \brief Parse the weight type from a legacy poll contract.
//!
//! \param value A numeric value extracted from the "<SHARETYPE>" field that
//! matches a value enumerated on \c PollWeightType.
//!
//! \return The matching weight type or the value of "unknown" when the string
//! does not contain a valid weight type number.
//!
PollWeightType ParseWeightType(const std::string& value)
{
        uint32_t parsed = 0;

        if (!ParseUInt32(value, &parsed) || parsed > Poll::WeightType::MAX) {
            return PollWeightType::UNKNOWN;
        }

        return static_cast<PollWeightType>(parsed);
}

//!
//! \brief Parse the poll duration from a legacy poll contract.
//!
//! \param value A numeric value extracted from the "<DAYS>" field.
//!
//! \return The parsed number of days or zero when the string does not contain
//! a valid number.
//!
uint32_t ParseDurationDays(const std::string& value)
{
    uint32_t duration = 0;

    if (!ParseUInt32(value, &duration)) {
        error("%s: Unable to parse poll duration from legacy poll contract. Input string is %s.",
              __func__, value);
    }

    return duration;
}

//!
//! \brief Parse the set of available choices from a legacy poll contract.
//!
//! \param value A semicolon-delimited string of labels extracted from the
//! "<ANSWERS>" field. Each label represents one choice.
//!
//! \return The parsed set of poll choices.
//!
Poll::ChoiceList ParseChoices(const std::string& value)
{
    Poll::ChoiceList choices;

    for (auto& label : split(value, ";")) {
        choices.Add(std::move(label));
    }

    return choices;
}

//!
//! \brief Poll choices to return for polls with a yes/no/abstain response type.
//!
const Poll::ChoiceList g_yes_no_abstain_choices(std::vector<Poll::Choice> {
    { "Yes"     },
    { "No"      },
    { "Abstain" },
});
} // Anonymous namespace

// -----------------------------------------------------------------------------
// Class: Poll
// -----------------------------------------------------------------------------

Poll::Poll()
    : m_type(PollType::UNKNOWN)
    , m_weight_type(PollWeightType::UNKNOWN)
    , m_response_type(PollResponseType::UNKNOWN)
    , m_duration_days(0)
    , m_timestamp(0)
{
}

Poll::Poll(
    PollType type,
    PollWeightType weight_type,
    PollResponseType response_type,
    uint32_t duration_days,
    std::string title,
    std::string url,
    std::string question,
    ChoiceList choices,
    int64_t timestamp)
    : m_type(type)
    , m_weight_type(weight_type)
    , m_response_type(response_type)
    , m_duration_days(duration_days)
    , m_title(std::move(title))
    , m_url(std::move(url))
    , m_question(std::move(question))
    , m_choices(std::move(choices))
    , m_timestamp(timestamp)
{
}

Poll Poll::Parse(const std::string& title, const std::string& contract)
{
    return Poll(
        PollType::SURVEY,
        ParseWeightType(ExtractXML(contract, "<SHARETYPE>", "</SHARETYPE>")),
        // Legacy contracts only behaved as multiple-choice polls:
        PollResponseType::MULTIPLE_CHOICE,
        ParseDurationDays(ExtractXML(contract, "<DAYS>", "</DAYS>")),
        title,
        ExtractXML(contract, "<URL>", "</URL>"),
        ExtractXML(contract, "<QUESTION>", "</QUESTION>"),
        ParseChoices(ExtractXML(contract, "<ANSWERS>", "</ANSWERS>")),
        0);
}

bool Poll::WellFormed() const
{
    return m_type != PollType::UNKNOWN
        && m_type != PollType::OUT_OF_BOUND
        && m_weight_type != PollWeightType::UNKNOWN
        && m_weight_type != PollWeightType::OUT_OF_BOUND
        && m_response_type != PollResponseType::UNKNOWN
        && m_response_type != PollResponseType::OUT_OF_BOUND
        && m_duration_days >= MIN_DURATION_DAYS
        && m_duration_days <= MAX_DURATION_DAYS
        && !m_title.empty()
        && !m_url.empty()
        && m_choices.WellFormed(m_response_type.Value());
}

bool Poll::WellFormed(const uint32_t version) const
{
    if (!WellFormed()) {
        return false;
    }

    // Version 2+ poll contracts in block version 11 and greater disallow the
    // deprecated legacy vote weighing methods:
    //
    if (version >= 2) {
        switch (m_weight_type.Value()) {
            case PollWeightType::MAGNITUDE:
            case PollWeightType::CPID_COUNT:
            case PollWeightType::PARTICIPANT_COUNT:
                return false;
            default:
                break;
        }
    }

    return true;
}

bool Poll::IncludesMagnitudeWeight() const
{
    return m_weight_type == PollWeightType::BALANCE_AND_MAGNITUDE
        || m_weight_type == PollWeightType::MAGNITUDE;
}

bool Poll::AllowsMultipleChoices() const
{
    return m_response_type == PollResponseType::MULTIPLE_CHOICE;
}

int64_t Poll::Age(const int64_t now) const
{
    return now - m_timestamp;
}

bool Poll::Expired(const int64_t now) const
{
    return Age(now) > m_duration_days * 86400;
}

int64_t Poll::Expiration() const
{
    return m_timestamp + (m_duration_days * 86400);
}

const Poll::ChoiceList& Poll::Choices() const
{
    if (m_response_type == PollResponseType::YES_NO_ABSTAIN) {
        return g_yes_no_abstain_choices;
    }

    return m_choices;
}

std::string Poll::WeightTypeToString() const
{
    switch (m_weight_type.Value()) {
        case PollWeightType::UNKNOWN:
        case PollWeightType::OUT_OF_BOUND:          return _("Unknown");
        case PollWeightType::MAGNITUDE:             return _("Magnitude");
        case PollWeightType::BALANCE:               return _("Balance");
        case PollWeightType::BALANCE_AND_MAGNITUDE: return _("Magnitude+Balance");
        case PollWeightType::CPID_COUNT:            return _("CPID Count");
        case PollWeightType::PARTICIPANT_COUNT:     return _("Participant Count");
    }

    assert(false); // Suppress warning
}

std::string Poll::ResponseTypeToString() const
{
    switch (m_response_type.Value()) {
        case PollResponseType::UNKNOWN:
        case PollResponseType::OUT_OF_BOUND:    return _("Unknown");
        case PollResponseType::YES_NO_ABSTAIN:  return _("Yes/No/Abstain");
        case PollResponseType::SINGLE_CHOICE:   return _("Single Choice");
        case PollResponseType::MULTIPLE_CHOICE: return _("Multiple Choice");
    }

    assert(false); // Suppress warning
}

// -----------------------------------------------------------------------------
// Class: Poll::ChoiceList
// -----------------------------------------------------------------------------

using ChoiceList = Poll::ChoiceList;
using Choice = Poll::Choice;

ChoiceList::ChoiceList(std::vector<Choice> choices)
    : m_choices(std::move(choices))
{
}

ChoiceList::const_iterator ChoiceList::begin() const
{
    return m_choices.begin();
}

ChoiceList::const_iterator ChoiceList::end() const
{
    return m_choices.end();
}

size_t ChoiceList::size() const
{
    return m_choices.size();
}

bool ChoiceList::empty() const
{
    return m_choices.empty();
}

bool ChoiceList::WellFormed(const PollResponseType response_type) const
{
    if (response_type == PollResponseType::YES_NO_ABSTAIN) {
        return m_choices.empty();
    }

    return !m_choices.empty()
        && m_choices.size() <= POLL_MAX_CHOICES_SIZE
        && std::all_of(
            m_choices.begin(),
            m_choices.end(),
            [](const Choice& choice) { return choice.WellFormed(); });
}

bool ChoiceList::OffsetInRange(const size_t offset) const
{
    return offset < m_choices.size();
}

bool ChoiceList::LabelExists(const std::string& label) const
{
    return OffsetOf(label).operator bool();
}

std::optional<uint8_t> ChoiceList::OffsetOf(const std::string& label) const
{
    const auto iter = std::find_if(
        m_choices.begin(),
        m_choices.end(),
        [&](const Choice& choice) { return choice.m_label == label; });

    if (iter == m_choices.end()) {
        return std::nullopt;
    }

    return std::distance(m_choices.begin(), iter);
}

const Choice* ChoiceList::At(const size_t offset) const
{
    if (offset >= m_choices.size()) {
        return nullptr;
    }

    return &m_choices[offset];
}

void ChoiceList::Add(std::string label)
{
    m_choices.emplace_back(std::move(label));
}
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>

namespace {
  bool
  verifyUser(void)
  {
    uid_t consoleUID;
    CFStringRef result = SCDynamicStoreCopyConsoleUser(NULL, &consoleUID, NULL);
    if (! result) return false;
    CFRelease(result);

    return (getuid() == consoleUID);
  }
}

int
main(int argc, char **argv)
{
  if (argc != 3) {
    fprintf(stderr, "Usage: %s key value\n", argv[0]);
    return 1;
  }

  if (! verifyUser()) {
    return 1;
  }

  char name[512];
  snprintf(name, sizeof(name), "keyremap4macbook.%s", argv[1]);

  if (strcmp(argv[1], "socket_path") == 0) {
    char* value = argv[2];
    size_t oldlen = 0;
    size_t newlen = strlen(value) + 1;
    int error = sysctlbyname(name, NULL, &oldlen, value, newlen);

    if (error) {
      perror("sysctl");
      return 1;
    }

  } else {
    int value = atoi(argv[2]);

    size_t oldlen = 0;
    size_t newlen = sizeof(value);
    int error = sysctlbyname(name, NULL, &oldlen, &value, newlen);

    if (error) {
      perror("sysctl");
      return 1;
    }
  }

  return 0;
}
<commit_msg>apply uncrustify<commit_after>#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>

namespace {
  bool
  verifyUser(void)
  {
    uid_t consoleUID;
    CFStringRef result = SCDynamicStoreCopyConsoleUser(NULL, &consoleUID, NULL);
    if (! result) return false;
    CFRelease(result);

    return (getuid() == consoleUID);
  }
}

int
main(int argc, char** argv)
{
  if (argc != 3) {
    fprintf(stderr, "Usage: %s key value\n", argv[0]);
    return 1;
  }

  if (! verifyUser()) {
    return 1;
  }

  char name[512];
  snprintf(name, sizeof(name), "keyremap4macbook.%s", argv[1]);

  if (strcmp(argv[1], "socket_path") == 0) {
    char* value = argv[2];
    size_t oldlen = 0;
    size_t newlen = strlen(value) + 1;
    int error = sysctlbyname(name, NULL, &oldlen, value, newlen);

    if (error) {
      perror("sysctl");
      return 1;
    }

  } else {
    int value = atoi(argv[2]);

    size_t oldlen = 0;
    size_t newlen = sizeof(value);
    int error = sysctlbyname(name, NULL, &oldlen, &value, newlen);

    if (error) {
      perror("sysctl");
      return 1;
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include <cstdint>
#include <ctime>
#include <initializer_list>
#include <unordered_map>

#include <boost/variant.hpp>

#include "utils/underlying.hpp"

#if defined(__clang__) || defined(GCC47)
#else
namespace std {

typedef double double_t;

} // namespace std
#endif

namespace blackhole {

namespace log {

typedef boost::variant<
    std::uint8_t,
    std::uint32_t,
    std::int32_t,
    std::uint64_t,
    std::int64_t,
    std::double_t,
    std::time_t,
    std::string
> attribute_value_t;

namespace attribute {

enum class scope : std::uint8_t {
    local       = 1 << 0,   /* user-defined event attributes*/
    event       = 1 << 1,   /* not user-defined event attributes, like timestamp or message */
    global      = 1 << 2,   /* logger object attributes*/
    thread      = 1 << 3,   /* thread attributes */
    universe    = 1 << 4    /* singleton attributes for entire application */
};

typedef aux::underlying_type<scope>::type scope_underlying_type;

static const scope DEFAULT_SCOPE = scope::local;

} // namespace attribute

struct attribute_t {
    attribute_value_t value;
    attribute::scope scope;

    attribute_t() :
        value(std::uint8_t(0)),
        scope(attribute::DEFAULT_SCOPE)
    {}

    attribute_t(const attribute_value_t& value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(value),
        scope(type)
    {}

    // Force compiler to keep enum values according to its underlying type.
    // It is needed, cause for weakly-typed enums its underlying type and its values underlying
    // types may vary, which leads to exception while extracting from variant.
    template<typename T, class = typename std::enable_if<std::is_enum<T>::value>::type>
    attribute_t(T value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(static_cast<typename aux::underlying_type<T>::type>(value)),
        scope(type)
    {}
};

typedef std::pair<
    std::string,
    attribute_t
> attribute_pair_t;

typedef std::unordered_map<
    attribute_pair_t::first_type,
    attribute_pair_t::second_type
> attributes_t;

} // namespace log

inline log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace attribute {

// Dynamic attribute factory function.
template<typename T>
inline
log::attribute_pair_t make(const std::string& name, const T& value, log::attribute::scope scope = log::attribute::DEFAULT_SCOPE) {
    return std::make_pair(name, log::attribute_t(value, scope));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<commit_msg>Code style.<commit_after>#pragma once

#include <cstdint>
#include <ctime>
#include <initializer_list>
#include <unordered_map>

#include <boost/variant.hpp>

#include "utils/underlying.hpp"

#if defined(__clang__) || defined(GCC47)
#else
namespace std {

typedef double double_t;

} // namespace std
#endif

namespace blackhole {

namespace log {

typedef boost::variant<
    std::uint8_t,
    std::uint32_t,
    std::int32_t,
    std::uint64_t,
    std::int64_t,
    std::double_t,
    std::time_t,
    std::string
> attribute_value_t;

namespace attribute {

enum class scope : std::uint8_t {
    local       = 1 << 0,   /* user-defined event attributes*/
    event       = 1 << 1,   /* not user-defined event attributes, like timestamp or message */
    global      = 1 << 2,   /* logger object attributes*/
    thread      = 1 << 3,   /* thread attributes */
    universe    = 1 << 4    /* singleton attributes for entire application */
};

typedef aux::underlying_type<scope>::type scope_underlying_type;

static const scope DEFAULT_SCOPE = scope::local;

} // namespace attribute

struct attribute_t {
    attribute_value_t value;
    attribute::scope scope;

    attribute_t() :
        value(std::uint8_t(0)),
        scope(attribute::DEFAULT_SCOPE)
    {}

    attribute_t(const attribute_value_t& value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(value),
        scope(type)
    {}

    // Force compiler to keep enum values according to its underlying type.
    // It is needed, cause for weakly-typed enums its underlying type and its values underlying
    // types may vary, which leads to exception while extracting from variant.
    template<typename T, class = typename std::enable_if<std::is_enum<T>::value>::type>
    attribute_t(T value, attribute::scope type = attribute::DEFAULT_SCOPE) :
        value(static_cast<typename aux::underlying_type<T>::type>(value)),
        scope(type)
    {}
};

typedef std::pair<
    std::string,
    attribute_t
> attribute_pair_t;

typedef std::unordered_map<
    attribute_pair_t::first_type,
    attribute_pair_t::second_type
> attributes_t;

} // namespace log

inline log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace attribute {

// Dynamic attribute factory function.
template<typename T>
inline log::attribute_pair_t make(const std::string& name, const T& value, log::attribute::scope scope = log::attribute::DEFAULT_SCOPE) {
    return std::make_pair(name, log::attribute_t(value, scope));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<|endoftext|>


<commit_before>#pragma once

#include <ctime>
#include <initializer_list>
#include <utility>

#include "blackhole/attribute/name.hpp"
#include "blackhole/attribute/set.hpp"
#include "blackhole/attribute/view.hpp"
#include "blackhole/attribute/traits.hpp"
#include "blackhole/attribute/value.hpp"
#include "blackhole/detail/config/underlying.hpp"

namespace blackhole {

namespace attribute {

/*!
 * Simple typedef for attributes initializer list.
 * Useful when specifying local attributes.
 */
typedef std::initializer_list<std::pair<name_t, value_t>> list;

/*!
 * Dynamic attribute factory function.
 */
template<typename T>
inline
pair_t
make(const name_t& name, const T& value) {
    return std::make_pair(name, attribute_t(value));
}

template<typename T>
inline
pair_t
make(const name_t& name, T&& value) {
    return std::make_pair(name, attribute_t(std::forward<T>(value)));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const set_view_t& attributes, const name_t& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const set_view_t& attributes, const name_t& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<commit_msg>[Code Clean] Drop unnecessary function.<commit_after>#pragma once

#include <ctime>
#include <initializer_list>
#include <utility>

#include "blackhole/attribute/name.hpp"
#include "blackhole/attribute/set.hpp"
#include "blackhole/attribute/view.hpp"
#include "blackhole/attribute/traits.hpp"
#include "blackhole/attribute/value.hpp"
#include "blackhole/detail/config/underlying.hpp"

namespace blackhole {

namespace attribute {

/*!
 * Simple typedef for attributes initializer list.
 * Useful when specifying local attributes.
 */
typedef std::initializer_list<std::pair<name_t, value_t>> list;

/*!
 * Dynamic attribute factory function.
 */
template<typename T>
inline
pair_t
make(const name_t& name, T&& value) {
    return std::make_pair(name, attribute_t(std::forward<T>(value)));
}

// Attribute packing/unpacking/extracting.
template<typename T, class = void>
struct traits {
    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const set_view_t& attributes, const name_t& name) {
        return boost::get<T>(attributes.at(name).value);
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename aux::underlying_type<T>::type underlying_type;

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const set_view_t& attributes, const name_t& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name).value));
    }
};

} // namespace attribute

} // namespace blackhole
<|endoftext|>


<commit_before><commit_msg>gui: switching check for text height outside loop, swap order of checking height limits<commit_after><|endoftext|>


<commit_before><commit_msg>gui: on detailed view draw rows without considering minimum resolution<commit_after><|endoftext|>


<commit_before>/* Copyright (C) 2011 Xavier Pujol.

   This file is part of fplll. fplll is free software: you
   can redistribute it and/or modify it under the terms of the GNU Lesser
   General Public License as published by the Free Software Foundation,
   either version 2.1 of the License, or (at your option) any later version.

   fplll is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with fplll. If not, see <http://www.gnu.org/licenses/>. */

/* Template source file */
#include "bkz.h"
#include "enumerate.h"

FPLLL_BEGIN_NAMESPACE

static double getSlope(const vector<double>& x) {
  int n = x.size();
  double iMean = (n - 1) * 0.5, xMean = 0, v1 = 0, v2 = 0;
  for (int i = 0; i < n; i++) {
    xMean += x[i];
  }
  xMean /= n;
  for (int i = 0; i < n; i++) {
    v1 += (i - iMean) * (x[i] - xMean);
    v2 += (i - iMean) * (i - iMean);
  }
  return v1 / v2;
}

template<class FT>
bool BKZAutoAbort<FT>::testAbort() {
  const int MAX_NO_DEC = 5;
  FT f, logF;
  long expo;
  if (x.empty()) x.resize(numRows);
  for (int i = 0; i < numRows; i++) {
    m.updateGSORow(i);
    f = m.getRExp(i, i, expo);
    logF.log(f, GMP_RNDU);
    x[i] = logF.get_d() + expo * log(2.0);
  }
  double newSlope = -getSlope(x);
  if (noDec == -1 || newSlope < oldSlope)
    noDec = 0;
  else
    noDec++;
  oldSlope = min(oldSlope, newSlope);
  return noDec >= MAX_NO_DEC;
}

template<class FT>
BKZReduction<FT>::BKZReduction(MatGSO<Integer, FT>& m,
        LLLReduction<Integer, FT>& lllObj, const BKZParam& param) :
  status(RED_SUCCESS), param(param), m(m), lllObj(lllObj)
{
  for (numRows = m.d; numRows > 0 && m.b[numRows - 1].is_zero(); numRows--) {}
  this->delta = param.delta;
}

template<class FT>
BKZReduction<FT>::~BKZReduction() {
}

template<class FT>
bool BKZReduction<FT>::svpReduction(int kappa, int blockSize, bool& clean) {
  long maxDistExpo;

  int lllStart = (param.flags & BKZ_BOUNDED_LLL) ? kappa : 0;

  if (!lllObj.lll(lllStart, kappa, kappa + blockSize)) {
    return setStatus(lllObj.status);
  }
  if (lllObj.nSwaps > 0) {
    clean = false;
  }
  maxDist = m.getRExp(kappa, kappa, maxDistExpo);
  deltaMaxDist.mul(delta, maxDist);
  vector<FT>& solCoord = evaluator.solCoord;
  solCoord.clear();
  Enumeration::enumerate(m, maxDist, maxDistExpo, evaluator, emptySubTree,
            emptySubTree, kappa, kappa + blockSize, param.pruning);
  if (solCoord.empty()) {
    return setStatus(RED_ENUM_FAILURE);
  }

  // Is it already in the basis ?
  int nzVectors = 0, iVector = -1;
  for (int i = 0; i < blockSize; i++) {
    if (!solCoord[i].is_zero()) {
      nzVectors++;
      if (iVector == -1 && (solCoord[i].get_d() == 1 || solCoord[i].get_d() == -1))
        iVector = i;
    }
  }
  FPLLL_DEBUG_CHECK(nzVectors > 0);

  if (maxDist >= deltaMaxDist) {
    return true; // Do nothing
  }

  if (nzVectors == 1) {
    // Yes, it is another vector
    FPLLL_DEBUG_CHECK(iVector != -1 && iVector != 0);
    m.moveRow(kappa + iVector, kappa);
    if (!lllObj.sizeReduction(kappa, kappa + 1))
      return setStatus(lllObj.status);
  }
  else {
    // No, general case
    int d = m.d;
    m.createRow();
    m.rowOpBegin(d, d + 1);
    for (int i = 0; i < blockSize; i++) {
      m.row_addmul(d, kappa + i, solCoord[i]);
    }
    m.rowOpEnd(d, d + 1);
    m.moveRow(d, kappa);
    if (!lllObj.lll(kappa, kappa, kappa + blockSize + 1))
      return setStatus(lllObj.status);
    FPLLL_DEBUG_CHECK(m.b[kappa + blockSize].is_zero());
    m.moveRow(kappa + blockSize, d);
    m.removeLastRow();
  }
  clean = false;
  return true;
}

template<class FT>
bool BKZReduction<FT>::bkzLoop(int& kappaMax, int& nIter, bool& clean) {
  int flags = param.flags;
  for (int iter = 0;; iter++) {
    if (iter >= numRows - 1) break;
    int kappa = iter;
    // SVP-reduces a block
    int blockSize = min(param.blockSize, numRows - kappa);
    if (!svpReduction(kappa, blockSize, clean)) return false;
    if ((flags & BKZ_VERBOSE) && kappaMax < kappa && clean) {
      cerr << "Block [1-" << kappa + 1
           << "] BKZ-reduced for the first time" << endl;
      kappaMax = kappa;
    }
    nIter++;
  }
  return true;
}

template<class FT>
bool BKZReduction<FT>::bkz() {
  int flags = param.flags;
  int finalStatus = RED_SUCCESS;

  if (param.blockSize < 2)
    return setStatus(RED_SUCCESS);

  int kappaMax = 0;
  int iLoop, nIter = 0;
  BKZAutoAbort<FT> autoAbort(m, numRows);

  if (flags & BKZ_VERBOSE) printParams();
  cputimeStart = cputime();

  m.discoverAllRows();

  for (iLoop = 0;; iLoop++) {
    if ((flags & BKZ_MAX_LOOPS) && iLoop >= param.maxLoops) {
      finalStatus = RED_BKZ_LOOPS_LIMIT;
      break;
    }
    if ((flags & BKZ_MAX_TIME) && (cputime() - cputimeStart) * 0.001 >= param.maxTime) {
      finalStatus = RED_BKZ_TIME_LIMIT;
      break;
    }
    if ((flags & BKZ_AUTO_ABORT) && autoAbort.testAbort()) break;
    bool clean = true;
    if (!bkzLoop(kappaMax, nIter, clean)) return false;
    if (clean || param.blockSize >= numRows) break;
    if (flags & BKZ_VERBOSE) {
      FT r0;
      Float fr0;
      long expo;
      r0 = m.getRExp(0, 0, expo);
      fr0 = r0.get_d();
      fr0.mul_2si(fr0, expo);
      cerr << "End of BKZ loop, time=" << cputime() * 0.001 << ", r_0 = " << fr0 << endl;
    }
  }
  return setStatus(finalStatus);
}

template<class FT>
void BKZReduction<FT>::printParams() {
  cerr << "Entering BKZ"
       << "\nblocksize = " << param.blockSize << endl;
}

template<class FT>
bool BKZReduction<FT>::setStatus(int newStatus) {
  status = newStatus;
  if (param.flags & BKZ_VERBOSE) {
    if (status == RED_SUCCESS)
      cerr << "End of BKZ: success" << endl;
    else
      cerr << "End of BKZ: failure: " << RED_STATUS_STR[status] << endl;
  }
  return status == RED_SUCCESS;
}

FPLLL_END_NAMESPACE
<commit_msg>Small simplification of bkzLoop()<commit_after>/* Copyright (C) 2011 Xavier Pujol.

   This file is part of fplll. fplll is free software: you
   can redistribute it and/or modify it under the terms of the GNU Lesser
   General Public License as published by the Free Software Foundation,
   either version 2.1 of the License, or (at your option) any later version.

   fplll is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with fplll. If not, see <http://www.gnu.org/licenses/>. */

/* Template source file */
#include "bkz.h"
#include "enumerate.h"

FPLLL_BEGIN_NAMESPACE

static double getSlope(const vector<double>& x) {
  int n = x.size();
  double iMean = (n - 1) * 0.5, xMean = 0, v1 = 0, v2 = 0;
  for (int i = 0; i < n; i++) {
    xMean += x[i];
  }
  xMean /= n;
  for (int i = 0; i < n; i++) {
    v1 += (i - iMean) * (x[i] - xMean);
    v2 += (i - iMean) * (i - iMean);
  }
  return v1 / v2;
}

template<class FT>
bool BKZAutoAbort<FT>::testAbort() {
  const int MAX_NO_DEC = 5;
  FT f, logF;
  long expo;
  if (x.empty()) x.resize(numRows);
  for (int i = 0; i < numRows; i++) {
    m.updateGSORow(i);
    f = m.getRExp(i, i, expo);
    logF.log(f, GMP_RNDU);
    x[i] = logF.get_d() + expo * log(2.0);
  }
  double newSlope = -getSlope(x);
  if (noDec == -1 || newSlope < oldSlope)
    noDec = 0;
  else
    noDec++;
  oldSlope = min(oldSlope, newSlope);
  return noDec >= MAX_NO_DEC;
}

template<class FT>
BKZReduction<FT>::BKZReduction(MatGSO<Integer, FT>& m,
        LLLReduction<Integer, FT>& lllObj, const BKZParam& param) :
  status(RED_SUCCESS), param(param), m(m), lllObj(lllObj)
{
  for (numRows = m.d; numRows > 0 && m.b[numRows - 1].is_zero(); numRows--) {}
  this->delta = param.delta;
}

template<class FT>
BKZReduction<FT>::~BKZReduction() {
}

template<class FT>
bool BKZReduction<FT>::svpReduction(int kappa, int blockSize, bool& clean) {
  long maxDistExpo;

  int lllStart = (param.flags & BKZ_BOUNDED_LLL) ? kappa : 0;

  if (!lllObj.lll(lllStart, kappa, kappa + blockSize)) {
    return setStatus(lllObj.status);
  }
  if (lllObj.nSwaps > 0) {
    clean = false;
  }
  maxDist = m.getRExp(kappa, kappa, maxDistExpo);
  deltaMaxDist.mul(delta, maxDist);
  vector<FT>& solCoord = evaluator.solCoord;
  solCoord.clear();
  Enumeration::enumerate(m, maxDist, maxDistExpo, evaluator, emptySubTree,
            emptySubTree, kappa, kappa + blockSize, param.pruning);
  if (solCoord.empty()) {
    return setStatus(RED_ENUM_FAILURE);
  }

  // Is it already in the basis ?
  int nzVectors = 0, iVector = -1;
  for (int i = 0; i < blockSize; i++) {
    if (!solCoord[i].is_zero()) {
      nzVectors++;
      if (iVector == -1 && (solCoord[i].get_d() == 1 || solCoord[i].get_d() == -1))
        iVector = i;
    }
  }
  FPLLL_DEBUG_CHECK(nzVectors > 0);

  if (maxDist >= deltaMaxDist) {
    return true; // Do nothing
  }

  if (nzVectors == 1) {
    // Yes, it is another vector
    FPLLL_DEBUG_CHECK(iVector != -1 && iVector != 0);
    m.moveRow(kappa + iVector, kappa);
    if (!lllObj.sizeReduction(kappa, kappa + 1))
      return setStatus(lllObj.status);
  }
  else {
    // No, general case
    int d = m.d;
    m.createRow();
    m.rowOpBegin(d, d + 1);
    for (int i = 0; i < blockSize; i++) {
      m.row_addmul(d, kappa + i, solCoord[i]);
    }
    m.rowOpEnd(d, d + 1);
    m.moveRow(d, kappa);
    if (!lllObj.lll(kappa, kappa, kappa + blockSize + 1))
      return setStatus(lllObj.status);
    FPLLL_DEBUG_CHECK(m.b[kappa + blockSize].is_zero());
    m.moveRow(kappa + blockSize, d);
    m.removeLastRow();
  }
  clean = false;
  return true;
}

template<class FT>
bool BKZReduction<FT>::bkzLoop(int& kappaMax, int& nIter, bool& clean) {
  int flags = param.flags;
  for (int kappa = 0; kappa < numRows-1; kappa++) {
    // SVP-reduces a block
    int blockSize = min(param.blockSize, numRows - kappa);
    if (!svpReduction(kappa, blockSize, clean)) return false;
    if ((flags & BKZ_VERBOSE) && kappaMax < kappa && clean) {
      cerr << "Block [1-" << kappa + 1
           << "] BKZ-reduced for the first time" << endl;
      kappaMax = kappa;
    }
    nIter++;
  }
  return true;
}

template<class FT>
bool BKZReduction<FT>::bkz() {
  int flags = param.flags;
  int finalStatus = RED_SUCCESS;

  if (param.blockSize < 2)
    return setStatus(RED_SUCCESS);

  int kappaMax = 0;
  int iLoop, nIter = 0;
  BKZAutoAbort<FT> autoAbort(m, numRows);

  if (flags & BKZ_VERBOSE) printParams();
  cputimeStart = cputime();

  m.discoverAllRows();

  for (iLoop = 0;; iLoop++) {
    if ((flags & BKZ_MAX_LOOPS) && iLoop >= param.maxLoops) {
      finalStatus = RED_BKZ_LOOPS_LIMIT;
      break;
    }
    if ((flags & BKZ_MAX_TIME) && (cputime() - cputimeStart) * 0.001 >= param.maxTime) {
      finalStatus = RED_BKZ_TIME_LIMIT;
      break;
    }
    if ((flags & BKZ_AUTO_ABORT) && autoAbort.testAbort()) break;
    bool clean = true;
    if (!bkzLoop(kappaMax, nIter, clean)) return false;
    if (clean || param.blockSize >= numRows) break;
    if (flags & BKZ_VERBOSE) {
      FT r0;
      Float fr0;
      long expo;
      r0 = m.getRExp(0, 0, expo);
      fr0 = r0.get_d();
      fr0.mul_2si(fr0, expo);
      cerr << "End of BKZ loop, time=" << cputime() * 0.001 << ", r_0 = " << fr0 << endl;
    }
  }
  return setStatus(finalStatus);
}

template<class FT>
void BKZReduction<FT>::printParams() {
  cerr << "Entering BKZ"
       << "\nblocksize = " << param.blockSize << endl;
}

template<class FT>
bool BKZReduction<FT>::setStatus(int newStatus) {
  status = newStatus;
  if (param.flags & BKZ_VERBOSE) {
    if (status == RED_SUCCESS)
      cerr << "End of BKZ: success" << endl;
    else
      cerr << "End of BKZ: failure: " << RED_STATUS_STR[status] << endl;
  }
  return status == RED_SUCCESS;
}

FPLLL_END_NAMESPACE
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Authentication.h"

/* system implementation headers */
#ifdef HAVE_KRB5
#include <com_err.h>
#endif
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <assert.h>

#ifdef HAVE_KRB5
krb5_context   Authentication::context        = NULL;
krb5_ccache    Authentication::cc             = NULL;
krb5_principal Authentication::client;
krb5_creds     Authentication::my_creds;
#endif
bool           Authentication::authentication = false;

Authentication::Authentication() : trusted(false)
{
}

#ifdef HAVE_KRB5
void Authentication::init(const char *address, int port, const char *password)
{
  assert(context == NULL);
  assert(cc == NULL);

  krb5_error_code retval;
  char            ccfile[MAXPATHLEN+6]; // FILE:path+\0

  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    com_err("bzfs:", retval, "while initializing krb5");

  // Gettin a default cache different for any bzfs process
  sprintf(ccfile, "FILE:/tmp/krb5cc_p%ld", (long)getpid());
  if (context && (retval = krb5_cc_set_default_name(context, ccfile)))
    com_err("bzfs:", retval, "setting default cache");
  unlink(ccfile+strlen("FILE:"));

  // Getting credential cache
  if (!retval && (retval = krb5_cc_default(context, &cc)))
    com_err("bzfs:", retval, "getting credentials cache");

  // Getting principal identifier
  char serverPort[8];
  snprintf(serverPort, sizeof(serverPort), "%d", port);
  if (cc && (retval = krb5_sname_to_principal(context, address, serverPort,
					      KRB5_NT_SRV_HST, &client)))
    com_err("bzfs:", retval, "getting principal name");

  // Initing credential cache
  if (!retval && (retval = krb5_cc_initialize(context, cc, client)))
    com_err("bzfs:", retval, "initializing credential cache");

  char intPassword[128];
  strncpy(intPassword, password, 128);
  intPassword[127] = 0;
  // Get credentials for server
  if (!retval && (retval = krb5_get_init_creds_password(context, &my_creds,
 							client, intPassword,
 							krb5_prompter_posix,
 							NULL, 0, NULL, NULL)))
    com_err("bzfs:", retval, "getting credential");

  // Store credentials in cache
  if (!retval && (retval = krb5_cc_store_cred(context, cc, &my_creds)))
    com_err("bzfs:", retval, "storing credential in cache");

  if (retval)
    authentication = false;
}
#else
void Authentication::init(const char *, int , const char *)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::setPrincipalName(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_error_code retval;
  char            remotePrincipal[1024];

  memcpy(remotePrincipal, buf, len);
  remotePrincipal[len] = 0;

  if ((retval = krb5_parse_name(context, remotePrincipal, &server)))
    com_err("bzfs", retval, "parsing remote name");
}
#else
void Authentication::setPrincipalName(char *, int)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::verifyCredential(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_creds        creds;
  krb5_error_code   retval;
  krb5_creds       *new_creds;

  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));

  creds.second_ticket.length = len;
  creds.second_ticket.data   = buf;

  // Check authentication info
  if ((retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc, &creds,
				     &new_creds)))
    com_err("bzfs", retval, "getting user-user ticket");
  else
    trusted = true;
}
#else
void Authentication::verifyCredential(char *, int)
{
}
#endif // HAVE_KRB5

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>unistd?<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Authentication.h"

/* system implementation headers */
#ifdef HAVE_KRB5
#include <com_err.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <string>
#include <assert.h>

#ifdef HAVE_KRB5
krb5_context   Authentication::context        = NULL;
krb5_ccache    Authentication::cc             = NULL;
krb5_principal Authentication::client;
krb5_creds     Authentication::my_creds;
#endif
bool           Authentication::authentication = false;

Authentication::Authentication() : trusted(false)
{
}

#ifdef HAVE_KRB5
void Authentication::init(const char *address, int port, const char *password)
{
  assert(context == NULL);
  assert(cc == NULL);

  krb5_error_code retval;
  char            ccfile[MAXPATHLEN+6]; // FILE:path+\0

  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    com_err("bzfs:", retval, "while initializing krb5");

  // Gettin a default cache different for any bzfs process
  sprintf(ccfile, "FILE:/tmp/krb5cc_p%ld", (long)getpid());
  if (context && (retval = krb5_cc_set_default_name(context, ccfile)))
    com_err("bzfs:", retval, "setting default cache");
  unlink(ccfile+strlen("FILE:"));

  // Getting credential cache
  if (!retval && (retval = krb5_cc_default(context, &cc)))
    com_err("bzfs:", retval, "getting credentials cache");

  // Getting principal identifier
  char serverPort[8];
  snprintf(serverPort, sizeof(serverPort), "%d", port);
  if (cc && (retval = krb5_sname_to_principal(context, address, serverPort,
					      KRB5_NT_SRV_HST, &client)))
    com_err("bzfs:", retval, "getting principal name");

  // Initing credential cache
  if (!retval && (retval = krb5_cc_initialize(context, cc, client)))
    com_err("bzfs:", retval, "initializing credential cache");

  char intPassword[128];
  strncpy(intPassword, password, 128);
  intPassword[127] = 0;
  // Get credentials for server
  if (!retval && (retval = krb5_get_init_creds_password(context, &my_creds,
 							client, intPassword,
 							krb5_prompter_posix,
 							NULL, 0, NULL, NULL)))
    com_err("bzfs:", retval, "getting credential");

  // Store credentials in cache
  if (!retval && (retval = krb5_cc_store_cred(context, cc, &my_creds)))
    com_err("bzfs:", retval, "storing credential in cache");

  if (retval)
    authentication = false;
}
#else
void Authentication::init(const char *, int , const char *)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::setPrincipalName(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_error_code retval;
  char            remotePrincipal[1024];

  memcpy(remotePrincipal, buf, len);
  remotePrincipal[len] = 0;

  if ((retval = krb5_parse_name(context, remotePrincipal, &server)))
    com_err("bzfs", retval, "parsing remote name");
}
#else
void Authentication::setPrincipalName(char *, int)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::verifyCredential(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_creds        creds;
  krb5_error_code   retval;
  krb5_creds       *new_creds;

  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));

  creds.second_ticket.length = len;
  creds.second_ticket.data   = buf;

  // Check authentication info
  if ((retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc, &creds,
				     &new_creds)))
    com_err("bzfs", retval, "getting user-user ticket");
  else
    trusted = true;
}
#else
void Authentication::verifyCredential(char *, int)
{
}
#endif // HAVE_KRB5

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include <map>
#include <vector>
#include <string>
#include <time.h>
#include "NFComm/NFPluginModule/NFIPluginManager.h"
#include "NFComm/NFCore/NFQueue.h"
#include "NFComm/RapidXML/rapidxml.hpp"
#include "NFComm/RapidXML/rapidxml_iterators.hpp"
#include "NFComm/RapidXML/rapidxml_print.hpp"
#include "NFComm/RapidXML/rapidxml_utils.hpp"
#include "NFComm/NFPluginModule/NFPlatform.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dirent.h"
#include <sys/stat.h>
#include <errno.h>

#if NF_PLATFORM == NF_PLATFORM_WIN
#include <io.h>
#include <windows.h>
#include <conio.h>
#else
#include <iconv.h>
#include <unistd.h>
#include <cstdio>
#include <dirent.h>
#include <sys/stat.h>
#endif

bool GetPluginNameList(std::string& strPlugin, std::vector<std::string>& pluginList, std::string& configPath)
{
	rapidxml::file<> fdoc(strPlugin.c_str());
	rapidxml::xml_document<>  doc;
	doc.parse<0>(fdoc.data());

	rapidxml::xml_node<>* pRoot = doc.first_node();
	for (rapidxml::xml_node<>* pPluginNode = pRoot->first_node("Plugin"); pPluginNode; pPluginNode = pPluginNode->next_sibling("Plugin"))
	{
		const char* strPluginName = pPluginNode->first_attribute("Name")->value();
		const char* strMain = pPluginNode->first_attribute("Main")->value();
		pluginList.push_back(std::string(strPluginName));
	}

	rapidxml::xml_node<>* pPluginAppNode = pRoot->first_node("APPID");
	if (!pPluginAppNode)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	const char* strAppID = pPluginAppNode->first_attribute("Name")->value();
	if (!strAppID)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	rapidxml::xml_node<>* pPluginConfigPathNode = pRoot->first_node("ConfigPath");
	if (!pPluginConfigPathNode)
	{
		//NFASSERT(0, "There are no ConfigPath", __FILE__, __FUNCTION__);
		return false;
	}

	if (NULL == pPluginConfigPathNode->first_attribute("Name"))
	{
		//NFASSERT(0, "There are no ConfigPath.Name", __FILE__, __FUNCTION__);
		return false;
	}

	configPath = pPluginConfigPathNode->first_attribute("Name")->value();

	return true;
}

int CopyFile(std::string& SourceFile, std::string& NewFile)
{
	ifstream in;
	ofstream out;
	in.open(SourceFile.c_str(), ios::binary);//Դļ
	if (in.fail())//Դļʧ
	{
		cout << "Error 1: Fail to open the source file." << endl;
		in.close();
		out.close();
		return 0;
	}
	out.open(NewFile.c_str(), ios::binary);//Ŀļ
	if (out.fail())//ļʧ
	{
		cout << "Error 2: Fail to create the new file." << endl;
		out.close();
		in.close();
		return 0;
	}
	else//ļ
	{
		out << in.rdbuf();
		out.close();
		in.close();
		return 1;
	}
}

std::vector<std::string> GetFileListInFolder(std::string folderPath, int depth)
{
	std::vector<std::string> result;
#if NF_PLATFORM == NF_PLATFORM_WIN
	_finddata_t FileInfo;
	std::string strfind = folderPath + "\\*";
	long long Handle = _findfirst(strfind.c_str(), &FileInfo);

	if (Handle == -1L)
	{
		std::cerr << "can not match the folder path" << std::endl;
		exit(-1);
	}
	do {
		//жǷĿ¼
		if (FileInfo.attrib & _A_SUBDIR)
		{
			//Ҫ
			if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
			{
				std::string newPath = folderPath + "\\" + FileInfo.name;
				//dfsFolder(newPath, depth);
				auto newResult = GetFileListInFolder(newPath, depth);
				result.insert(result.begin(), newResult.begin(), newResult.end());
			}
		}
		else
		{

			std::string filename = (folderPath + "\\" + FileInfo.name);
			result.push_back(filename);
		}
	} while (_findnext(Handle, &FileInfo) == 0);

	_findclose(Handle);
#else
	DIR *pDir;
	struct dirent *ent;
	char childpath[512];
	char absolutepath[512];
	pDir = opendir(folderPath.c_str());
	memset(childpath, 0, sizeof(childpath));
	while ((ent = readdir(pDir)) != NULL)
	{
		if (ent->d_type & DT_DIR)
		{
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
			{
				continue;
			}
			std::string childpath = folderPath + "/" + ent->d_name;
			auto newResult = GetFileListInFolder(childpath, depth);
			result.insert(result.begin(), newResult.begin(), newResult.end());
		}
		else
		{
			sprintf(absolutepath, "%s/%s", folderPath.c_str(), ent->d_name);
			result.push_back(absolutepath);
		}
	}

	sort(result.begin(), result.end());//
#endif
	return result;
}

void printResult(int result, std::string& strName)
{
	if (result == 1)
	{
		printf("Copy file: %s success!\n", strName.c_str());
	}
	else
	{
		printf("Copy file: %s failed!\n", strName.c_str());
	}
}

int main()
{
	std::vector<std::string> fileList;
#ifdef NF_DEBUG_MODE
	fileList = GetFileListInFolder("../../Debug", 10);
#else
	fileList = GetFileListInFolder("../../Release", 10);
#endif
	for (auto fileName : fileList)
	{
		if (fileName.find("Plugin.xml") != std::string::npos)
		{
			printf("Reading xml file: %s\n", fileName.c_str());

			std::vector<std::string> pluginList;
			std::string configPath = "";
			GetPluginNameList(fileName, pluginList, configPath);
			if (pluginList.size() > 0 && configPath != "")
			{
#if NF_PLATFORM == NF_PLATFORM_WIN
				pluginList.push_back("libprotobuf");
				pluginList.push_back("NFMessageDefine");
#else
				pluginList.push_back("NFMessageDefine");
#endif
				pluginList.push_back("NFPluginLoader");
				configPath = "../" + configPath;
				configPath = fileName.substr(0, fileName.find_last_of("/")) + "/" + configPath;

				for (std::string name : pluginList)
				{
#if NF_PLATFORM == NF_PLATFORM_WIN

#else

#endif

					int result = 0;
					if (name == "NFPluginLoader")
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.exe";
						auto strDes = des + "_d.exe";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d";
						auto strDes = des + "_d";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif

					}
					else
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.dll";
						auto strDes = des + "_d.dll";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/lib" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.so";
						auto strDes = des + "_d.so";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif
					}
				}
			}
		}
	}

	std::cin.ignore();
	return 0;
}<commit_msg>update<commit_after>#include <map>
#include <vector>
#include <string>
#include <time.h>
#include "NFComm/NFPluginModule/NFIPluginManager.h"
#include "NFComm/NFCore/NFQueue.h"
#include "NFComm/RapidXML/rapidxml.hpp"
#include "NFComm/RapidXML/rapidxml_iterators.hpp"
#include "NFComm/RapidXML/rapidxml_print.hpp"
#include "NFComm/RapidXML/rapidxml_utils.hpp"
#include "NFComm/NFPluginModule/NFPlatform.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>

#if NF_PLATFORM == NF_PLATFORM_WIN
#include <io.h>
#include <windows.h>
#include <conio.h>
#else
#include <iconv.h>
#include <unistd.h>
#include <cstdio>
#include <dirent.h>
#include <sys/stat.h>
#endif

bool GetPluginNameList(std::string& strPlugin, std::vector<std::string>& pluginList, std::string& configPath)
{
	rapidxml::file<> fdoc(strPlugin.c_str());
	rapidxml::xml_document<>  doc;
	doc.parse<0>(fdoc.data());

	rapidxml::xml_node<>* pRoot = doc.first_node();
	for (rapidxml::xml_node<>* pPluginNode = pRoot->first_node("Plugin"); pPluginNode; pPluginNode = pPluginNode->next_sibling("Plugin"))
	{
		const char* strPluginName = pPluginNode->first_attribute("Name")->value();
		const char* strMain = pPluginNode->first_attribute("Main")->value();
		pluginList.push_back(std::string(strPluginName));
	}

	rapidxml::xml_node<>* pPluginAppNode = pRoot->first_node("APPID");
	if (!pPluginAppNode)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	const char* strAppID = pPluginAppNode->first_attribute("Name")->value();
	if (!strAppID)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	rapidxml::xml_node<>* pPluginConfigPathNode = pRoot->first_node("ConfigPath");
	if (!pPluginConfigPathNode)
	{
		//NFASSERT(0, "There are no ConfigPath", __FILE__, __FUNCTION__);
		return false;
	}

	if (NULL == pPluginConfigPathNode->first_attribute("Name"))
	{
		//NFASSERT(0, "There are no ConfigPath.Name", __FILE__, __FUNCTION__);
		return false;
	}

	configPath = pPluginConfigPathNode->first_attribute("Name")->value();

	return true;
}

int CopyFile(std::string& SourceFile, std::string& NewFile)
{
	ifstream in;
	ofstream out;
	in.open(SourceFile.c_str(), ios::binary);//Դļ
	if (in.fail())//Դļʧ
	{
		cout << "Error 1: Fail to open the source file." << endl;
		in.close();
		out.close();
		return 0;
	}
	out.open(NewFile.c_str(), ios::binary);//Ŀļ
	if (out.fail())//ļʧ
	{
		cout << "Error 2: Fail to create the new file." << endl;
		out.close();
		in.close();
		return 0;
	}
	else//ļ
	{
		out << in.rdbuf();
		out.close();
		in.close();
		return 1;
	}
}

std::vector<std::string> GetFileListInFolder(std::string folderPath, int depth)
{
	std::vector<std::string> result;
#if NF_PLATFORM == NF_PLATFORM_WIN
	_finddata_t FileInfo;
	std::string strfind = folderPath + "\\*";
	long long Handle = _findfirst(strfind.c_str(), &FileInfo);

	if (Handle == -1L)
	{
		std::cerr << "can not match the folder path" << std::endl;
		exit(-1);
	}
	do {
		//жǷĿ¼
		if (FileInfo.attrib & _A_SUBDIR)
		{
			//Ҫ
			if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
			{
				std::string newPath = folderPath + "\\" + FileInfo.name;
				//dfsFolder(newPath, depth);
				auto newResult = GetFileListInFolder(newPath, depth);
				result.insert(result.begin(), newResult.begin(), newResult.end());
			}
		}
		else
		{

			std::string filename = (folderPath + "\\" + FileInfo.name);
			result.push_back(filename);
		}
	} while (_findnext(Handle, &FileInfo) == 0);

	_findclose(Handle);
#else
	DIR *pDir;
	struct dirent *ent;
	char childpath[512];
	char absolutepath[512];
	pDir = opendir(folderPath.c_str());
	memset(childpath, 0, sizeof(childpath));
	while ((ent = readdir(pDir)) != NULL)
	{
		if (ent->d_type & DT_DIR)
		{
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
			{
				continue;
			}
			std::string childpath = folderPath + "/" + ent->d_name;
			auto newResult = GetFileListInFolder(childpath, depth);
			result.insert(result.begin(), newResult.begin(), newResult.end());
		}
		else
		{
			sprintf(absolutepath, "%s/%s", folderPath.c_str(), ent->d_name);
			result.push_back(absolutepath);
		}
	}

	sort(result.begin(), result.end());//
#endif
	return result;
}

void printResult(int result, std::string& strName)
{
	if (result == 1)
	{
		printf("Copy file: %s success!\n", strName.c_str());
	}
	else
	{
		printf("Copy file: %s failed!\n", strName.c_str());
	}
}

int main()
{
	std::vector<std::string> fileList;
#ifdef NF_DEBUG_MODE
	fileList = GetFileListInFolder("../../Debug", 10);
#else
	fileList = GetFileListInFolder("../../Release", 10);
#endif
	for (auto fileName : fileList)
	{
		if (fileName.find("Plugin.xml") != std::string::npos)
		{
			printf("Reading xml file: %s\n", fileName.c_str());

			std::vector<std::string> pluginList;
			std::string configPath = "";
			GetPluginNameList(fileName, pluginList, configPath);
			if (pluginList.size() > 0 && configPath != "")
			{
#if NF_PLATFORM == NF_PLATFORM_WIN
				pluginList.push_back("libprotobuf");
				pluginList.push_back("NFMessageDefine");
#else
				pluginList.push_back("NFMessageDefine");
#endif
				pluginList.push_back("NFPluginLoader");
				configPath = "../" + configPath;
				configPath = fileName.substr(0, fileName.find_last_of("/")) + "/" + configPath;

				for (std::string name : pluginList)
				{
#if NF_PLATFORM == NF_PLATFORM_WIN

#else

#endif

					int result = 0;
					if (name == "NFPluginLoader")
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.exe";
						auto strDes = des + "_d.exe";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d";
						auto strDes = des + "_d";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif

					}
					else
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.dll";
						auto strDes = des + "_d.dll";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/lib" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.so";
						auto strDes = des + "_d.so";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif
					}
				}
			}
		}
	}

	std::cin.ignore();
	return 0;
}<|endoftext|>


<commit_before>#include <string>
#include <vector>

#include <benchpress/benchpress.hpp>

BENCHMARK("example", [](benchpress::context* ctx) {
    for (size_t i = 0; i < ctx->num_iterations(); ++i) {
        std::cout << "hello" << std::endl;
    }
})
<commit_msg>Bench performance of variable-bit-size integers<commit_after>#include <string>
#include <vector>

#include <benchpress/benchpress.hpp>

#include <tudocomp/ds/uint_t.hpp>

using namespace benchpress;

const uint32_t N_SUB_ITER = 10000;

#define ADD x += 1;
#define ADD2 ADD ADD
#define ADD3 ADD2 ADD2
#define ADD4 ADD3 ADD3
#define ADD5 ADD4 ADD4
#define ADD6 ADD5 ADD5
#define ADD7 ADD6 ADD6
#define ADD8 ADD7 ADD7
#define ADD9 ADD8 ADD8
#define ADD10 ADD9 ADD9
#define ADD11 ADD10 ADD10
#define ADD12 ADD11 ADD11
#define ADD13 ADD12 ADD12

struct Inc {
    template<class T>
    static void op(T& x) {
        x += 1;
    }
};

struct NoOp {
    template<class T>
    static void op(T& x) {
    }
};

template<class T, class Op = Inc>
inline void int_test(benchpress::context* ctx) {
    T n = 0;

    for (size_t i = 0; i < ctx->num_iterations(); ++i) {
        escape(&n);

        for (size_t j = 0; j < N_SUB_ITER; j++) {
            Op::op(n);
        }
    }

    escape(&n);
}

BENCHMARK("inc::empty", (int_test<uint32_t, NoOp>))
BENCHMARK("inc::uint8_t", int_test<uint8_t>)
BENCHMARK("inc::uint16_t", int_test<uint16_t>)
BENCHMARK("inc::uint32_t", int_test<uint32_t>)
BENCHMARK("inc::uint64_t", int_test<uint64_t>)
BENCHMARK("inc::uint_t<1>", int_test<uint_t<1>>)
BENCHMARK("inc::uint_t<8>", int_test<uint_t<8>>)
BENCHMARK("inc::uint_t<16>", int_test<uint_t<16>>)
BENCHMARK("inc::uint_t<24>", int_test<uint_t<24>>)
BENCHMARK("inc::uint_t<32>", int_test<uint_t<32>>)
BENCHMARK("inc::uint_t<40>", int_test<uint_t<40>>)
BENCHMARK("inc::uint_t<64>", int_test<uint_t<64>>)

BENCHMARK("ref::uint32_t&", [](benchpress::context* ctx) {
    uint32_t n = 0;

    for (size_t i = 0; i < ctx->num_iterations(); ++i) {
        escape(&n);
        auto& x = n;
        for (size_t j = 0; j < N_SUB_ITER; j++) {
            x += 1;
        }
    }

    escape(&n);
})

BENCHMARK("ref::uint_t<40>&", [](benchpress::context* ctx) {
    uint_t<40> n = 0;

    for (size_t i = 0; i < ctx->num_iterations(); ++i) {
        escape(&n);
        auto& x = n;
        for (size_t j = 0; j < N_SUB_ITER; j++) {
            x += 1;
        }
    }

    escape(&n);
})
<|endoftext|>


<commit_before>// Standard headers
#include <thread>
#include <iostream>

// Internal headers
#include "InputArgs.hpp"

int main(int argc, char **argv)
{
  unsigned int n = std::thread::hardware_concurrency();
  std::cout << n << " concurrent threads are supported.\n";

  InputArgs input_args;

  std::cout << input_args.n_threads << std::endl;

  return 0;
}
<commit_msg>Read options with 'InputArgs'<commit_after>// Standard headers
#include <cstdlib>
#include <iostream>

// Internal headers
#include "InputArgs.hpp"

int main(int argc, char **argv)
{
  if (argc != 6) {
    std::cerr << "USAGE: "
              << argv[0]
              << "[0|n] [f|m] p x [d|s]"
              << std::endl;
    return EXIT_FAILURE;
  }

  InputArgs input_args(argc, argv);

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewcontactofmasterpagedescriptor.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 16:35:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX
#define _SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SDR_MASTERPAGEDESCRIPTOR_HXX
#include <sdrmasterpagedescriptor.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////
// predeclarations
class SfxItemSet;
class Bitmap;
class MapMode;

namespace sdr
{
    namespace contact
    {
        class OwnMasterPagePainter;
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        class ViewContactOfMasterPageDescriptor : public ViewContact
        {
        protected:
            // the owner of this ViewContact. Set from constructor and not
            // to be changed in any way.
            sdr::MasterPageDescriptor&                      mrMasterPageDescriptor;

            // the painter for the MasterPage content
            ::sdr::contact::OwnMasterPagePainter*           mpMasterPagePainter;

            // Create a Object-Specific ViewObjectContact, set ViewContact and
            // ObjectContact. Always needs to return something. Default is to create
            // a standard ViewObjectContact containing the given ObjectContact and *this
            virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);

            // method to recalculate the PaintRectangle if the validity flag shows that
            // it is invalid. The flag is set from GetPaintRectangle, thus the implementation
            // only needs to refresh maPaintRectangle itself.
            virtual void CalcPaintRectangle();

        public:
            // basic constructor
            ViewContactOfMasterPageDescriptor(sdr::MasterPageDescriptor& rDescriptor);

            // The destructor.
            virtual ~ViewContactOfMasterPageDescriptor();

            // access to MasterPageDescriptor
            sdr::MasterPageDescriptor& GetMasterPageDescriptor() const
            {
                return mrMasterPageDescriptor;
            }

            // When ShouldPaintObject() returns sal_True, the object itself is painted and
            // PaintObject() is called.
            virtual sal_Bool ShouldPaintObject(DisplayInfo& rDisplayInfo, const ViewObjectContact& rAssociatedVOC);

            // #115593# Paint this object. This is before evtl. SubObjects get painted. It needs to return
            // sal_True when something was pained and the paint output rectangle in rPaintRectangle.
            virtual sal_Bool PaintObject(DisplayInfo& rDisplayInfo, Rectangle& rPaintRectangle, const ViewObjectContact& rAssociatedVOC);
            virtual ViewContact* GetParentContact() const;

            // React on changes of the object of this ViewContact
            virtual void ActionChanged();

            // Interface method for receiving buffered MasterPage render data from
            // VOCOfMasterPageDescriptor. Called from instances of VOCOfMasterPageDescriptor.
            void OfferBufferedData(const Bitmap& rBitmap, const MapMode& rMapMode);

            // Interface method for VOCOfMasterPageDescriptor to ask for buffered data. If
            // the page is the sane and the MapMode is the same, return the Bitmap.
            Bitmap RequestBufferedData(const MapMode& rMapMode);

            // #i37869# Support method to paint borders and grids which are overpainted from
            // this MasterPage content to let the MasterPage appear as page background
            void PaintBackgroundPageBordersAndGrids(DisplayInfo& rDisplayInfo, const ViewObjectContact& rAssociatedVOC);
        };
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif //_SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX

// eof
<commit_msg>INTEGRATION: CWS hedaburemove01 (1.7.38); FILE MERGED 2007/03/29 16:42:56 vg 1.7.38.2: RESYNC: (1.7-1.8); FILE MERGED 2007/02/09 16:10:08 vg 1.7.38.1: #72503# get rid of hedabu procedure: Moving headers to svx/inc/svx and correspondent necessary changes<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewcontactofmasterpagedescriptor.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 17:02:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX
#define _SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SDR_MASTERPAGEDESCRIPTOR_HXX
#include <svx/sdrmasterpagedescriptor.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////
// predeclarations
class SfxItemSet;
class Bitmap;
class MapMode;

namespace sdr
{
    namespace contact
    {
        class OwnMasterPagePainter;
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        class ViewContactOfMasterPageDescriptor : public ViewContact
        {
        protected:
            // the owner of this ViewContact. Set from constructor and not
            // to be changed in any way.
            sdr::MasterPageDescriptor&                      mrMasterPageDescriptor;

            // the painter for the MasterPage content
            ::sdr::contact::OwnMasterPagePainter*           mpMasterPagePainter;

            // Create a Object-Specific ViewObjectContact, set ViewContact and
            // ObjectContact. Always needs to return something. Default is to create
            // a standard ViewObjectContact containing the given ObjectContact and *this
            virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact);

            // method to recalculate the PaintRectangle if the validity flag shows that
            // it is invalid. The flag is set from GetPaintRectangle, thus the implementation
            // only needs to refresh maPaintRectangle itself.
            virtual void CalcPaintRectangle();

        public:
            // basic constructor
            ViewContactOfMasterPageDescriptor(sdr::MasterPageDescriptor& rDescriptor);

            // The destructor.
            virtual ~ViewContactOfMasterPageDescriptor();

            // access to MasterPageDescriptor
            sdr::MasterPageDescriptor& GetMasterPageDescriptor() const
            {
                return mrMasterPageDescriptor;
            }

            // When ShouldPaintObject() returns sal_True, the object itself is painted and
            // PaintObject() is called.
            virtual sal_Bool ShouldPaintObject(DisplayInfo& rDisplayInfo, const ViewObjectContact& rAssociatedVOC);

            // #115593# Paint this object. This is before evtl. SubObjects get painted. It needs to return
            // sal_True when something was pained and the paint output rectangle in rPaintRectangle.
            virtual sal_Bool PaintObject(DisplayInfo& rDisplayInfo, Rectangle& rPaintRectangle, const ViewObjectContact& rAssociatedVOC);
            virtual ViewContact* GetParentContact() const;

            // React on changes of the object of this ViewContact
            virtual void ActionChanged();

            // Interface method for receiving buffered MasterPage render data from
            // VOCOfMasterPageDescriptor. Called from instances of VOCOfMasterPageDescriptor.
            void OfferBufferedData(const Bitmap& rBitmap, const MapMode& rMapMode);

            // Interface method for VOCOfMasterPageDescriptor to ask for buffered data. If
            // the page is the sane and the MapMode is the same, return the Bitmap.
            Bitmap RequestBufferedData(const MapMode& rMapMode);

            // #i37869# Support method to paint borders and grids which are overpainted from
            // this MasterPage content to let the MasterPage appear as page background
            void PaintBackgroundPageBordersAndGrids(DisplayInfo& rDisplayInfo, const ViewObjectContact& rAssociatedVOC);
        };
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif //_SDR_CONTACT_VIEWCONTACTOFMASTERPAGEDESCRIPTOR_HXX

// eof
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014—2016 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <vector>
#include "Phrase.hpp"
#include "UnitBezier.h"
#include "TimeType.h"

namespace choreograph
{

class Curve
{
public:
  enum Type {
    Bezier,
    Hold,
    Linear
  };

  Curve() = default;
  explicit Curve(Type t):
    _type(t)
  {}
  explicit Curve(const BezierInterpolant &bezier):
    _type(Bezier),
    _bezier(bezier)
  {}

  float              solve(float t) const;
  void               setType(Type type) { _type = type; }
  void               hold() { _type = Hold; }
  BezierInterpolant& bezier() { _type = Bezier; return _bezier; }
private:
  Type              _type = Linear;
  BezierInterpolant _bezier;
};

inline float Curve::solve(float t) const
{
  switch (_type) {
    case Bezier:
      return _bezier.solve(t);
    break;
    case Hold:
      return 0.0f;
    break;
    case Linear:
      return t;
    break;
    default:
      return t;
    break;
  }
}

///
/// Simple channel concept with bezier interpolation between keys.
/// Goals:
/// - Easy serialization
/// - Easy to create graphical manipulation tools.
///   - Support direct manipulation of animation data.
///   - Avoid deeply nested information. Flat hierarchy.
/// - Flexible enough to create an AfterEffects-style timeline.
///   - Separate motion path with bezier interpolation for full effect.
///   - Get time along section with channel, calculate value using path.
///   - Channel for timing, with key values corresponding to control points on spatial curve.
///
/// Good for animating single values, like floats or quaternions.
/// For vector types, use a channel per component (and maybe add a group type to associate them).
/// Grouping type could be a manipulator/animator type class that reads/writes multiple channels.
///
template <typename T>
class Channel
{
public:
  struct Key {
    Key(T value, Time time):
      value(value),
      time(time)
    {}
    T    value;
    Time time;
  };

  class KeyManipulator
  {
  public:
    KeyManipulator(Key &current, Key *previous, Key *next, Curve *c1, Curve *c2):
      _current(current),
      _previous(previous),
      _next(next),
      _curve_in(c1),
      _curve_out(c2)
    {}

    void setValue(const T &value) {
      _current.value = value;
    }
    T    value() const {
      return _current.value;
    }
    T    previousValue() const {
      return _previous ? _previous->value : value();
    }
    T    nextValue() const {
      return _next ? _next->value : value();
    }
    Time time() const {
      return _current.time;
    }
    Time nextTime() const {
      return _next ? _next->time : std::numeric_limits<Time>::max();
    }
    Time previousTime() const {
      return _previous ? _previous->time : 0;
    }
    void setTime(Time t) {
      _current.time = std::min(std::max(t, previousTime()), nextTime());
    }
    bool isFirst() const { return _previous == nullptr; }
    bool isLast() const { return _next == nullptr; }

    Curve* curveOut() { return _curve_out; }
    Curve* curveIn() { return _curve_in; }
  private:
    Key   &_current;
    Key   *_previous = nullptr;
    Key   *_next = nullptr;
    Curve *_curve_in = nullptr;
    Curve *_curve_out = nullptr;
  };

  Channel() = default;

  /// Return the value of the channel at a given time.
  T value(Time at_time) const;
  /// Return the interpolated value between two keys.
  /// If you keep track of keys yourself, this is faster.
  T interpolatedValue(size_t curve_index, Time at_time) const;

  /// Returns the index of the starting key for the current time.
  /// The curve lies between two keys.
  size_t index(Time at_time) const;
  size_t lastIndex() const { return _keys.empty() ? 0 : _keys.size() - 1; }

  /// Append a key to the list of keys, positioned at \offset time after the previous key.
  Channel& appendKeyAfter(T value, Time offset) {
    if (! _keys.empty()) {
      _curves.emplace_back();
    }
    _keys.emplace_back(value, duration() + offset);
    return *this;
  }
  /// Insert a key at the given time.
  Channel& insertKey(T value, Time at_time);
  /// Insert multiple keys.
  template <typename ... Keys>
  Channel& insertKey(T value, Time at_time, Keys... keys);

  Time     duration() const { return _keys.empty() ? 0 : _keys.back().time; }
  const std::vector<Key>&   keys() const { return _keys; }
  const std::vector<Curve>& curves() const { return _curves; }

  /// Returns a manipulator to adjust properties of the requested key.
  KeyManipulator keyControl(size_t key_index);

  // TODO: remove general mutability from keys/curves in favor of KeyManipulators.
  std::vector<Key>&   mutableKeys() { return _keys; }
  std::vector<Curve>& mutableCurves() { return _curves; }

private:
  std::vector<Key>   _keys;
  // may make polymorphic in future (like phrases are). Basically just an ease fn.
  // Compare std::function<float (float)> for max flexibility against custom class.
  std::vector<Curve> _curves;
};

#pragma mark - Channel Template Implementation

template <typename T>
size_t Channel<T>::index(Time at_time) const {

  if( at_time <= 0 ) {
    return 0;
  }
  else if ( at_time >= this->duration() ) {
    return lastIndex();
  }

  for (auto i = 0; i < _keys.size() - 1; i += 1) {
    auto &a = _keys[i], &b = _keys[i + 1];
    if (a.time <= at_time && b.time >= at_time) {
      return i;
    }
  }
  return lastIndex();
}

template <typename T>
T Channel<T>::value(Time at_time) const {
  if (at_time >= duration()) {
    return _keys.back().value;
  }
  else if (at_time <= 0.0) {
    return _keys.front().value;
  }

  return interpolatedValue(index(at_time), at_time);
}

template <typename T>
T Channel<T>::interpolatedValue(size_t curve_index, Time at_time) const {
  auto &a = _keys[curve_index];
  auto &b = _keys[curve_index + 1];
  auto &c = _curves[curve_index];

  auto x = (at_time - a.time) / (b.time - a.time);
  auto t = c.solve(x);
  return lerpT(a.value, b.value, t);
}

template <typename T>
Channel<T>& Channel<T>::insertKey(T value, Time at_time) {
  if (_keys.empty()) {
    _keys.emplace_back(value, at_time);
    return *this;
  }

  auto i = index(at_time);
  if (_curves.empty()) {
    _curves.emplace_back(Curve::Linear);
  }
  else {
    _curves.insert(_curves.begin() + i, Curve(Curve::Linear));
  }
  _keys.insert(_keys.begin() + i + 1, {value, at_time});

  return *this;
}

template <typename T>
template <typename ... Keys>
Channel<T>& Channel<T>::insertKey(T value, Time at_time, Keys... keys)
{
    insertKey(value, at_time);
    insertKey(std::forward<Keys>(keys)...);
    return *this;
}

template <typename T>
typename Channel<T>::KeyManipulator Channel<T>::keyControl(size_t desired_index) {
  auto index = std::min(desired_index, _keys.size() - 1);
  auto &current = _keys[index];
  auto *previous = (index > 0) ? &_keys[index - 1] : nullptr;
  auto *next = (index < _keys.size() - 1) ? &_keys[index + 1] : nullptr;
  auto *c1 = (index > 0) ? &_curves[index - 1] : nullptr;
  auto *c2 = (index < _curves.size()) ? &_curves[index] : nullptr;
  return KeyManipulator(current, previous, next, c1, c2);
}

} // namepsace choreograph
<commit_msg>Accessor for curve type.<commit_after>/*
 * Copyright (c) 2014—2016 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <vector>
#include "Phrase.hpp"
#include "UnitBezier.h"
#include "TimeType.h"

namespace choreograph
{

class Curve
{
public:
  enum Type {
    Bezier,
    Hold,
    Linear
  };

  Curve() = default;
  explicit Curve(Type t):
    _type(t)
  {}
  explicit Curve(const BezierInterpolant &bezier):
    _type(Bezier),
    _bezier(bezier)
  {}

  float              solve(float t) const;
  void               setType(Type type) { _type = type; }
  void               hold() { _type = Hold; }
  BezierInterpolant& bezier() { _type = Bezier; return _bezier; }
  Type               type() const { return _type; }
private:
  Type              _type = Linear;
  BezierInterpolant _bezier;
};

inline float Curve::solve(float t) const
{
  switch (_type) {
    case Bezier:
      return _bezier.solve(t);
    break;
    case Hold:
      return 0.0f;
    break;
    case Linear:
      return t;
    break;
    default:
      return t;
    break;
  }
}

///
/// Simple channel concept with bezier interpolation between keys.
/// Goals:
/// - Easy serialization
/// - Easy to create graphical manipulation tools.
///   - Support direct manipulation of animation data.
///   - Avoid deeply nested information. Flat hierarchy.
/// - Flexible enough to create an AfterEffects-style timeline.
///   - Separate motion path with bezier interpolation for full effect.
///   - Get time along section with channel, calculate value using path.
///   - Channel for timing, with key values corresponding to control points on spatial curve.
///
/// Good for animating single values, like floats or quaternions.
/// For vector types, use a channel per component (and maybe add a group type to associate them).
/// Grouping type could be a manipulator/animator type class that reads/writes multiple channels.
///
template <typename T>
class Channel
{
public:
  struct Key {
    Key(T value, Time time):
      value(value),
      time(time)
    {}
    T    value;
    Time time;
  };

  class KeyManipulator
  {
  public:
    KeyManipulator(Key &current, Key *previous, Key *next, Curve *c1, Curve *c2):
      _current(current),
      _previous(previous),
      _next(next),
      _curve_in(c1),
      _curve_out(c2)
    {}

    void setValue(const T &value) {
      _current.value = value;
    }
    T    value() const {
      return _current.value;
    }
    T    previousValue() const {
      return _previous ? _previous->value : value();
    }
    T    nextValue() const {
      return _next ? _next->value : value();
    }
    Time time() const {
      return _current.time;
    }
    Time nextTime() const {
      return _next ? _next->time : std::numeric_limits<Time>::max();
    }
    Time previousTime() const {
      return _previous ? _previous->time : 0;
    }
    void setTime(Time t) {
      _current.time = std::min(std::max(t, previousTime()), nextTime());
    }
    bool isFirst() const { return _previous == nullptr; }
    bool isLast() const { return _next == nullptr; }

    Curve* curveOut() { return _curve_out; }
    Curve* curveIn() { return _curve_in; }
  private:
    Key   &_current;
    Key   *_previous = nullptr;
    Key   *_next = nullptr;
    Curve *_curve_in = nullptr;
    Curve *_curve_out = nullptr;
  };

  Channel() = default;

  /// Return the value of the channel at a given time.
  T value(Time at_time) const;
  /// Return the interpolated value between two keys.
  /// If you keep track of keys yourself, this is faster.
  T interpolatedValue(size_t curve_index, Time at_time) const;

  /// Returns the index of the starting key for the current time.
  /// The curve lies between two keys.
  size_t index(Time at_time) const;
  size_t lastIndex() const { return _keys.empty() ? 0 : _keys.size() - 1; }

  /// Append a key to the list of keys, positioned at \offset time after the previous key.
  Channel& appendKeyAfter(T value, Time offset) {
    if (! _keys.empty()) {
      _curves.emplace_back();
    }
    _keys.emplace_back(value, duration() + offset);
    return *this;
  }
  /// Insert a key at the given time.
  Channel& insertKey(T value, Time at_time);
  /// Insert multiple keys.
  template <typename ... Keys>
  Channel& insertKey(T value, Time at_time, Keys... keys);

  Time     duration() const { return _keys.empty() ? 0 : _keys.back().time; }
  const std::vector<Key>&   keys() const { return _keys; }
  const std::vector<Curve>& curves() const { return _curves; }

  /// Returns a manipulator to adjust properties of the requested key.
  KeyManipulator keyControl(size_t key_index);

  // TODO: remove general mutability from keys/curves in favor of KeyManipulators.
  std::vector<Key>&   mutableKeys() { return _keys; }
  std::vector<Curve>& mutableCurves() { return _curves; }

private:
  std::vector<Key>   _keys;
  // may make polymorphic in future (like phrases are). Basically just an ease fn.
  // Compare std::function<float (float)> for max flexibility against custom class.
  std::vector<Curve> _curves;
};

#pragma mark - Channel Template Implementation

template <typename T>
size_t Channel<T>::index(Time at_time) const {

  if( at_time <= 0 ) {
    return 0;
  }
  else if ( at_time >= this->duration() ) {
    return lastIndex();
  }

  for (auto i = 0; i < _keys.size() - 1; i += 1) {
    auto &a = _keys[i], &b = _keys[i + 1];
    if (a.time <= at_time && b.time >= at_time) {
      return i;
    }
  }
  return lastIndex();
}

template <typename T>
T Channel<T>::value(Time at_time) const {
  if (at_time >= duration()) {
    return _keys.back().value;
  }
  else if (at_time <= 0.0) {
    return _keys.front().value;
  }

  return interpolatedValue(index(at_time), at_time);
}

template <typename T>
T Channel<T>::interpolatedValue(size_t curve_index, Time at_time) const {
  auto &a = _keys[curve_index];
  auto &b = _keys[curve_index + 1];
  auto &c = _curves[curve_index];

  auto x = (at_time - a.time) / (b.time - a.time);
  auto t = c.solve(x);
  return lerpT(a.value, b.value, t);
}

template <typename T>
Channel<T>& Channel<T>::insertKey(T value, Time at_time) {
  if (_keys.empty()) {
    _keys.emplace_back(value, at_time);
    return *this;
  }

  auto i = index(at_time);
  if (_curves.empty()) {
    _curves.emplace_back(Curve::Linear);
  }
  else {
    _curves.insert(_curves.begin() + i, Curve(Curve::Linear));
  }
  _keys.insert(_keys.begin() + i + 1, {value, at_time});

  return *this;
}

template <typename T>
template <typename ... Keys>
Channel<T>& Channel<T>::insertKey(T value, Time at_time, Keys... keys)
{
    insertKey(value, at_time);
    insertKey(std::forward<Keys>(keys)...);
    return *this;
}

template <typename T>
typename Channel<T>::KeyManipulator Channel<T>::keyControl(size_t desired_index) {
  auto index = std::min(desired_index, _keys.size() - 1);
  auto &current = _keys[index];
  auto *previous = (index > 0) ? &_keys[index - 1] : nullptr;
  auto *next = (index < _keys.size() - 1) ? &_keys[index + 1] : nullptr;
  auto *c1 = (index > 0) ? &_curves[index - 1] : nullptr;
  auto *c2 = (index < _curves.size()) ? &_curves[index] : nullptr;
  return KeyManipulator(current, previous, next, c1, c2);
}

} // namepsace choreograph
<|endoftext|>