text:
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// **************   NOTICE  *******************************************
// Facebook 2019 - Notice of Changes
// This file has been modified to extract only the Raft implementation
// out of Kudu into a fork known as kuduraft.
// ********************************************************************

#include "kudu/consensus/leader_election.h"

#include <algorithm>
#include <mutex>
#include <ostream>
#include <type_traits>
#include <vector>

#include <boost/bind.hpp> // IWYU pragma: keep
#include <glog/logging.h>

#include "kudu/common/wire_protocol.h"
#include "kudu/consensus/consensus_peers.h"
#include "kudu/consensus/metadata.pb.h"
#include "kudu/consensus/quorum_util.h"
#include "kudu/gutil/bind.h"
#include "kudu/gutil/callback.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/port.h"
#include "kudu/gutil/stl_util.h"
#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/rpc/rpc_controller.h"
//#include "kudu/tserver/tserver.pb.h"
#include "kudu/util/logging.h"
#include "kudu/util/pb_util.h"
#include "kudu/util/status.h"

namespace kudu {
namespace consensus {
namespace {

// Comparator for PreviousVotePB
bool compare_PreviousVotePB(
    const PreviousVotePB& a, const PreviousVotePB& b) {
  return a.election_term() < b.election_term();
}

// Comparator for binary search in a sorted list of PreviousVotePB
bool compareTerm_PreviousVotePB(
    const int64_t a, const PreviousVotePB& b) {
  return a < b.election_term();
}
}

using std::string;
using std::vector;
using strings::Substitute;

///////////////////////////////////////////////////
// VoteCounter & FlexibleVoteCounter
///////////////////////////////////////////////////

VoteCounter::VoteCounter(int num_voters, int majority_size)
  : num_voters_(num_voters),
    majority_size_(majority_size),
    yes_votes_(0),
    no_votes_(0) {
  CHECK_LE(majority_size, num_voters);
  CHECK_GT(num_voters_, 0);
  CHECK_GT(majority_size_, 0);
}

Status VoteCounter::RegisterVote(
    const std::string& voter_uuid, const VoteInfo& vote_info,
    bool* is_duplicate) {
  // Handle repeated votes.
  if (PREDICT_FALSE(ContainsKey(votes_, voter_uuid))) {
    // Detect changed votes.
    const VoteInfo& prior_vote_info = votes_.at(voter_uuid);
    if (PREDICT_FALSE(prior_vote_info.vote != vote_info.vote)) {
      string msg = Substitute(
          "Peer $0 voted a different way twice in the same election. "
          "First vote: $1, second vote: $2.",
          voter_uuid, prior_vote_info.vote, vote_info.vote);
      return Status::InvalidArgument(msg);
    }

    // This was just a duplicate. Allow the caller to log it but don't change
    // the voting record.
    *is_duplicate = true;
    return Status::OK();
  }

  // Sanity check to ensure we did not exceed the allowed number of voters.
  if (PREDICT_FALSE(yes_votes_ + no_votes_ == num_voters_)) {
    // More unique voters than allowed!
    return Status::InvalidArgument(Substitute(
        "Vote from peer $0 would cause the number of votes to exceed the expected number of "
        "voters, which is $1. Votes already received from the following peers: {$2}",
        voter_uuid,
        num_voters_,
        JoinKeysIterator(votes_.begin(), votes_.end(), ", ")));
  }

  // This is a valid vote, so store it.
  InsertOrDie(&votes_, voter_uuid, vote_info);
  switch (vote_info.vote) {
    case VOTE_GRANTED:
      ++yes_votes_;
      break;
    case VOTE_DENIED:
      ++no_votes_;
      break;
  }
  *is_duplicate = false;
  return Status::OK();
}

bool VoteCounter::IsDecided() const {
  return yes_votes_ >= majority_size_ ||
         no_votes_ > num_voters_ - majority_size_;
}

Status VoteCounter::GetDecision(ElectionVote* decision) const {
  if (yes_votes_ >= majority_size_) {
    *decision = VOTE_GRANTED;
    return Status::OK();
  }
  if (no_votes_ > num_voters_ - majority_size_) {
    *decision = VOTE_DENIED;
    return Status::OK();
  }
  return Status::IllegalState("Vote not yet decided");
}

int VoteCounter::GetTotalVotesCounted() const {
  return yes_votes_ + no_votes_;
}

bool VoteCounter::AreAllVotesIn() const {
  return GetTotalVotesCounted() == num_voters_;
}

PotentialNextLeaderResponse::PotentialNextLeaderResponse(
    PotentialNextLeaderResponse::Status s) {
  status = s;
  potential_leader_uuid = "";
  potential_leader_term = -1;
}

PotentialNextLeaderResponse::PotentialNextLeaderResponse(
    PotentialNextLeaderResponse::Status s, const std::string& uuid,
    const int64_t term) {
  status = s;
  potential_leader_uuid = uuid;
  potential_leader_term = term;
}

void FlexibleVoteCounter::FetchTopologyInfo() {
  // Step 1: Compute number of voters in each region.
  // Also, computes the leader's region from its UUID.
  GetRegionalCountsFromConfig(
      config_, last_known_leader_.uuid, &voter_distribution_,
      &last_known_leader_region_);

  CHECK(config_.has_commit_rule());

  // Step 2: Compute the leader election quorum from the corresponding
  // data commit quorum. The requirement is for it to intersect with all the
  // data commit quorums and all the leader election quorums.
  for (const RegionRuleSpecPB& rule_spec :
      config_.commit_rule().rule_conjunctions()) {
    std::string region = rule_spec.region_identifier();

    if (region == "master") {
      depends_on_last_leader_ = true;

      // Note: We have populated the commit requirement for the master region
      // and are not resolving it now.
      InsertIfNotPresent(&le_quorum_requirement_, region, -1);
      continue;
    }

    // This will throw if the configuration is not properly defined.
    int commit_req_num = ParseCommitRequirement(
        rule_spec.commit_requirement());

    // At this point region is resolved and we should be able to
    // fetch its cardinalities.
    // TODO(ritwikyadav): It is possible that all voters in a region
    // have left the replicaset. Handle that case gracefully in a subsequent diff.
    int total_voters = FindOrDie(voter_distribution_, region);
    int region_majority = MajoritySize(total_voters);

    // commit_req_num is -1 in case of majority requirement.
    if (commit_req_num == -1) {
      commit_req_num = region_majority;
    }

    // We chose the maximum of the two conditions required for intersection
    // of leader election quorum with data commit quorum and for any two
    // leader election quorums to intersect with one another.
    int le_req_num = std::max(
        total_voters + 1 - commit_req_num, region_majority);

    InsertIfNotPresent(&le_quorum_requirement_, region, le_req_num);
  }

  ComputePessimisticLeaderElectionQuorum();
}

void FlexibleVoteCounter::ComputePessimisticLeaderElectionQuorum() {
  // If master region cannot be resolved, we choose the most pessimistic quorum.
  pessimistic_le_quorum_ = le_quorum_requirement_;

  if (!depends_on_last_leader_) {
    // If the quorum is not a function of the current master region, then it
    // is exactly the same as le_quorum_requirement_
    return;
  } else {
    // Removing unresolved master specification.
    pessimistic_le_quorum_.erase("master");
  }

  // Here we enforce the same requirements that were needed in the leader region in
  // all the regions which have voters.
  for (const std::pair<std::string, int>& region_count_pair :
      voter_distribution_) {
    int& pessimistic_le_count =
        LookupOrInsert(&pessimistic_le_quorum_, region_count_pair.first, 0);
    int region_majority_count = MajoritySize(region_count_pair.second);
    // It is possible that the region already had more stringent requirements.
    pessimistic_le_count = std::max(pessimistic_le_count, region_majority_count);
  }
}

FlexibleVoteCounter::FlexibleVoteCounter(
    int64_t election_term, const LastKnownLeader& last_known_leader,
    RaftConfigPB config)
  : VoteCounter(0, 0),
    election_term_(election_term),
    depends_on_last_leader_(false),
    last_known_leader_(last_known_leader),
    config_(std::move(config)) {
  num_voters_ = 0;

  FetchTopologyInfo();
  for (
      const std::pair<std::string, int>& regional_voter_count :
      voter_distribution_) {
    CHECK_GT(regional_voter_count.second, 0);
    num_voters_ += regional_voter_count.second;
    yes_vote_count_.emplace(regional_voter_count.first, 0);
    no_vote_count_.emplace(regional_voter_count.first, 0);
  }

  CHECK_GT(num_voters_, 0);

  // Flag to check if the quorum specification is non-empty for all
  // specifications.
  bool empty_quorum = false;
  for (const std::pair<std::string, int>& regional_quorum_count :
      le_quorum_requirement_) {
    if (regional_quorum_count.first == "master") {
      continue;
    }
    const std::map<std::string, int>::const_iterator total_voters =
        voter_distribution_.find(regional_quorum_count.first);
    // Make sure that voters are present in the region specified by quorum
    // requirement and their number is enough.
    CHECK(total_voters != voter_distribution_.end());
    CHECK_LE(regional_quorum_count.second, total_voters->second);
    if (regional_quorum_count.second <= 0) {
      empty_quorum = true;
    }
  }
  CHECK(!empty_quorum);

  for (const RaftPeerPB& peer : config_.peers()) {
    if (peer.member_type() == RaftPeerPB::VOTER) {
      uuid_to_region_.emplace(peer.permanent_uuid(), peer.attrs().region());
    }
  }
}

Status FlexibleVoteCounter::RegisterVote(
    const std::string& voter_uuid, const VoteInfo& vote_info,
    bool* is_duplicate) {
  Status s = VoteCounter::RegisterVote(
      voter_uuid, vote_info, is_duplicate);

  // No book-keeping required for duplicate votes.
  if (*is_duplicate) {
    return s;
  }

  if (!ContainsKey(uuid_to_region_, voter_uuid)) {
    return Status::InvalidArgument(
        Substitute("UUID {$0} not present in config.", voter_uuid));
  }

  const std::string& region = uuid_to_region_[voter_uuid];
  switch (vote_info.vote) {
    case VOTE_GRANTED:
      InsertIfNotPresent(&yes_vote_count_, region, 0);
      yes_vote_count_[region]++;
      break;
    case VOTE_DENIED:
      InsertIfNotPresent(&no_vote_count_, region, 0);
      no_vote_count_[region]++;
      break;
  }

  return s;
}

int FlexibleVoteCounter::FetchVotesRemainingInRegion(
    const std::string& region) const {
  const std::map<std::string, int>::const_iterator regional_yes_count =
      yes_vote_count_.find(region);
  const std::map<std::string, int>::const_iterator regional_no_count =
      no_vote_count_.find(region);
  const std::map<std::string, int>::const_iterator total_region_count =
      voter_distribution_.find(region);

  // All the following must at least be initialized to zero in the
  // constructor.
  CHECK(total_region_count != voter_distribution_.end());
  CHECK(regional_yes_count != yes_vote_count_.end());
  CHECK(regional_no_count != no_vote_count_.end());

  return total_region_count->second - regional_yes_count->second -
      regional_no_count->second;
}

std::map<string, int> FlexibleVoteCounter::ResolveQuorum(
    const std::string& leader_region) const {
  bool master_requirement_found = false;
  std::map<string, int> resolved_quorum;
  for (const std::pair<string, int>& quorum_spec : le_quorum_requirement_) {
    if (quorum_spec.first == "master") {
      master_requirement_found = true;
      int commit_requirement = quorum_spec.second;

      // We only allow "majority" tag with "master" region since
      // the complexity to support an arbitrary integer as the master's
      // requirement is high. For instance, if the number of votes required
      // in the master region is 5 but the master region has 3 voters, we will
      // never be able to promote out of that region (trapped master).
      CHECK(commit_requirement == -1);
      int total_voters = FindOrDie(voter_distribution_, leader_region);
      commit_requirement = MajoritySize(total_voters);

      resolved_quorum.insert(
          std::make_pair<>(leader_region, commit_requirement));
    } else {
      resolved_quorum.insert(quorum_spec);
    }
  }
  CHECK(master_requirement_found);
  return resolved_quorum;
}

std::pair<bool, bool> FlexibleVoteCounter::IsQuorumSatisfied(
    const std::map<std::string, int>& resolved_quorum) const {
  CHECK(!resolved_quorum.empty());

  bool quorum_satisfied = true;
  bool quorum_satisfaction_possible = true;

  std::map<std::string, int>::const_iterator it = resolved_quorum.begin();
  for (; it != resolved_quorum.end(); it++) {
    const string& region = it->first;
    const std::map<std::string, int>::const_iterator regional_yes_count =
        yes_vote_count_.find(region);
    const std::map<std::string, int>::const_iterator regional_no_count =
        no_vote_count_.find(region);
    const std::map<std::string, int>::const_iterator total_region_count =
        voter_distribution_.find(region);

    // All the following must at least be initialized to zero in the
    // constructor.
    CHECK(total_region_count != voter_distribution_.end());
    CHECK(regional_yes_count != yes_vote_count_.end());
    CHECK(regional_no_count != no_vote_count_.end());

    VLOG_WITH_PREFIX(3) << "Region: " << region
                        << " Total voters: " << total_region_count->second
                        << " Votes granted count: "
                        << regional_yes_count->second
                        << " Votes denied count: " << regional_no_count->second
                        << " Quorum requirement: " << it->second;

    if (total_region_count->second < it->second) {
      // This should never happen in practice because of pre-checks.
      VLOG_WITH_PREFIX(1) << "Total number of voters in region: " << region
                          << " is: " << total_region_count->second
                          << " but quorum requirement is: " << it->second;
      quorum_satisfied = false;
      quorum_satisfaction_possible = false;
      break;
    }

    if (regional_yes_count->second < it->second) {
      VLOG_WITH_PREFIX(2) << "Yes votes in region: " << region
                    << " are: " << regional_yes_count->second
                    << " but quorum requirement is: " << it->second;
      quorum_satisfied = false;
    }
    if (regional_no_count->second +
        it->second > total_region_count->second) {
      VLOG_WITH_PREFIX(2) << "Quorum satisfaction not possible in region: "
                          << region << " because of excessive no votes: "
                          << regional_no_count->second
                          << " Quorum requirement: " << it->second;
      quorum_satisfaction_possible = false;
    }
  }
  return std::make_pair<>(quorum_satisfied, quorum_satisfaction_possible);
}

std::pair<bool, bool>
FlexibleVoteCounter::FetchQuorumSatisfactionInfoFromVoteHistory(
    const std::string& leader_region,
    const RegionToVoterSet& region_to_voter_set) const {
  VLOG_WITH_PREFIX(1) << "Fetching quorum satisfaction info from "
                      << "vote history. Leader region: " << leader_region;
  bool quorum_satisfied = true;
  bool quorum_satisfaction_possible = true;
  const std::map<std::string, int>& resolved_quorum =
      ResolveQuorum(leader_region);
  std::map<std::string, int>::const_iterator quorum_it =
      resolved_quorum.begin();
  for ( ; quorum_it != resolved_quorum.end(); quorum_it++) {
    const std::string& region = quorum_it->first;
    int votes_received = 0;
    const RegionToVoterSet::const_iterator& rtvs_it =
        region_to_voter_set.find(region);
    if (rtvs_it != region_to_voter_set.end()) {
      votes_received = rtvs_it->second.size();
    }
    int commit_requirement = quorum_it->second;
    int votes_remaining = FetchVotesRemainingInRegion(region);
    VLOG_WITH_PREFIX(3) << "Region: " << region << " , Votes granted: "
                        << votes_received << " , Votes remaining: "
                        << votes_remaining << " , Commit Requirement: "
                        << commit_requirement;
    if (votes_received < commit_requirement) {
      quorum_satisfied = false;
    }
    if (votes_received + votes_remaining < commit_requirement) {
      quorum_satisfaction_possible = false;
    }
  }
  return std::make_pair<>(quorum_satisfied, quorum_satisfaction_possible);
}

void FlexibleVoteCounter::ConstructRegionWiseVoteCollation(
    const int64_t term,
    const std::string& leader_region,
    VoteHistoryCollation* vote_collation,
    VoteHistoryIteratorMap* it_map,
    int64_t* min_term) const {
  CHECK(vote_collation);
  CHECK(it_map);
  CHECK(min_term);

  vote_collation->clear();
  it_map->clear();
  *min_term = 0;

  VoteMap::const_iterator it = votes_.begin();
  while (it != votes_.end()) {
    const std::string& uuid = it->first;

    // Skip servers that are not in the region of the last known leader or
    // one of the regions that feature in the leader election quorum.
    std::map<std::string, std::string>::const_iterator reg_it =
        uuid_to_region_.find(uuid);
    if (reg_it == uuid_to_region_.end() ||
        reg_it->second != leader_region ||
        le_quorum_requirement_.find(reg_it->second) ==
            le_quorum_requirement_.end()) {
      continue;
    }
    const std::vector<PreviousVotePB>& pvh = it->second.previous_vote_history;

    // Find the voting record immediately after the term of the last known
    // leader. Skip if there is no history beyond the last known leader.
    std::vector<PreviousVotePB>::const_iterator vhi = std::upper_bound(
        pvh.begin(), pvh.end(), term, compareTerm_PreviousVotePB);
    if (vhi == pvh.end()) {
      continue;
    }
    const UUIDTermPair utp = std::make_pair<>(
        vhi->candidate_uuid(), vhi->election_term());

    // Update minimum term seen so far in the last known leader's region.
    if (reg_it->second == leader_region) {
      *min_term = std::min(*min_term, utp.second);
    }

    // Insert the iterator into the map and update the collation.
    // The collation is a map from (UUID, term) -> [region -> set(UUID)].
    // For each key (UUID - term pair), it represents all servers
    // (corresponding UUIDs) which voted for the key.
    InsertIfNotPresent(it_map, uuid, vhi);
    RegionToVoterSet& rtvs =
        LookupOrInsert(vote_collation, utp, RegionToVoterSet());
    std::set<std::string>& uuid_set =
        LookupOrInsert(&rtvs, reg_it->second, std::set<std::string>());
    uuid_set.insert(uuid);

    it++;
  }
}

void FlexibleVoteCounter::UpdateRegionWiseVoteCollation(
    const int64_t term,
    const std::string& leader_region,
    VoteHistoryCollation* vote_collation,
    VoteHistoryIteratorMap* it_map,
    int64_t* min_term) const {
  CHECK(vote_collation);
  CHECK(it_map);
  CHECK(min_term);

  // Advance all the iterators to after the term provided.
  VoteHistoryIteratorMap::iterator vhim_it = it_map->begin();
  while (vhim_it != it_map->end()) {
    VoteMap::const_iterator it = votes_.find(vhim_it->first);
    CHECK(it != votes_.end());
    const std::vector<PreviousVotePB>& pvh = it->second.previous_vote_history;
    vhim_it->second = std::upper_bound(
        vhim_it->second, pvh.end(), term, compareTerm_PreviousVotePB);
    if (vhim_it->second == pvh.end()) {
      vhim_it = it_map->erase(vhim_it);
    } else {
      vhim_it++;
    }
  }

  // Recreate the vote collation from scratch.
  // The collation is a map from (UUID, term) -> [region -> set(UUID)].
  vote_collation->clear();
  vhim_it = it_map->begin();
  while (vhim_it != it_map->end()) {
    const std::string& region = FindOrDie(uuid_to_region_, vhim_it->first);
    const UUIDTermPair utp = std::make_pair<>(
        vhim_it->second->candidate_uuid(),
        vhim_it->second->election_term());
    RegionToVoterSet& rtvs =
        LookupOrInsert(vote_collation, utp, RegionToVoterSet());
    std::set<std::string>& uuid_set =
        LookupOrInsert(&rtvs, region, std::set<std::string>());
    uuid_set.insert(vhim_it->first);

    // Update the min term.
    // Note: min_term should actually be max(min_term_per_region) but
    // we use min_term in the leader region only for simplicity. It does
    // not affect correctness.
    if (region == leader_region) {
      *min_term = std::min(*min_term, vhim_it->second->election_term());
    }
    vhim_it++;
  }
}

PotentialNextLeaderResponse FlexibleVoteCounter::GetPotentialNextLeader(
    const int64_t term, const std::string& leader_region) const {
  // Collate a mapping from UUID, term pair to an iterator in the
  // voting history.
  int64_t min_term;

  // Mapping from UUID term pair to a set of UUIDs that voted for it
  // grouped by their region.
  VoteHistoryCollation vote_collation;

  // Map from UUID to an iterator in its vote history.
  VoteHistoryIteratorMap it_map;
  ConstructRegionWiseVoteCollation(
      term, leader_region, &vote_collation, &it_map, &min_term);

  // Figure out the total number of voters, commit requirement and votes not
  // received so far.
  int total_voters_leader_region =
      FindOrDie(voter_distribution_, leader_region);
  int commit_requirement_leader_region =
      MajoritySize(total_voters_leader_region);
  int votes_not_received_leader_region =
      FetchVotesRemainingInRegion(leader_region);

  // If we haven't received enough votes from the leader region, there is no point
  // proceeding. We need to wait for more votes.
  if (votes_not_received_leader_region >= commit_requirement_leader_region) {
    return PotentialNextLeaderResponse(
        PotentialNextLeaderResponse::WAITING_FOR_MORE_VOTES);
  }

  // For each term greater than the term of the last known leader,
  // compute if some server could have won an election in that term. If not,
  // we consider the next available term from the voting histories and repeat
  // until all the history is exhausted.
  while (!vote_collation.empty()) {
    VoteHistoryCollation::iterator vhc_it = vote_collation.begin();
    for ( ; vhc_it != vote_collation.end(); vhc_it++) {
      if (vhc_it->first.second == min_term) {
        std::pair<bool, bool> quorum_satisfaction_info =
            FetchQuorumSatisfactionInfoFromVoteHistory(
                leader_region, vhc_it->second);
        if (quorum_satisfaction_info.first) {
          // Case 1: Some UUID, term pair has the requisite votes.
          // Return new potential leader UUID for this case.
          return PotentialNextLeaderResponse(
              PotentialNextLeaderResponse::POTENTIAL_NEXT_LEADER_DETECTED,
              vhc_it->first.first, min_term);
        } else if (quorum_satisfaction_info.second) {
          // This UUID, term pair could still have won. Need more data.
          return PotentialNextLeaderResponse(
              PotentialNextLeaderResponse::WAITING_FOR_MORE_VOTES);
        }
      }
    }

    // No UUID could have won an election in min_term, recompute vote
    // collations and min term.
    UpdateRegionWiseVoteCollation(
        min_term, leader_region, &vote_collation, &it_map, &min_term);
  }

  // Return victory for the current election term, if it satisfies the quorum.
  // Voting history suggests all intervening terms between the last known
  // leader's term and the current election's terms are defunct.
  return PotentialNextLeaderResponse(
      PotentialNextLeaderResponse::ALL_INTERMEDIATE_TERMS_DEFUNCT);
}

std::pair<bool, bool> FlexibleVoteCounter::GetQuorumState() const {
  // Step 0: If the quorum is not a function of the last leader's region,
  // return early.
  if (!depends_on_last_leader_) {
    return IsQuorumSatisfied(le_quorum_requirement_);
  }

  // Step 1: Check if pessimistic quorum is satisfied.
  std::pair<bool, bool> presult = IsQuorumSatisfied(pessimistic_le_quorum_);

  // Return pessimistic quorum result if the pessimistic quorum is satisfied or
  // if the pessimistic quorum cannot be satisfied and we depend on the
  // knowledge of the last leader without having it (eg. during bootstrap), we
  // should declare having lost the election or having insufficient votes to make
  // a decision.
  if (presult.first || last_known_leader_region_.empty()) {
    return presult;
  }

  // Step 2: Check if last known leader's quorum is satisfied and we directly
  // succeed term.
  if (election_term_ == last_known_leader_.election_term + 1) {
    CHECK(!last_known_leader_.uuid.empty());
    CHECK(!last_known_leader_region_.empty());
    return IsQuorumSatisfied(ResolveQuorum(last_known_leader_region_));
  }

  // Step 3: Find a possible successor at every stage or a determination that
  // there was no leader in this term.
  // Return possible successor, next term to consider.
  // Repeat step 3 until next term is the current election's term or the
  // quorum converges to pessimistic quorum.
  std::set<string> explored_leader_regions;

  std::string possible_leader_region = last_known_leader_region_;
  int64_t term_it = last_known_leader_.election_term;

  explored_leader_regions.insert(possible_leader_region);
  while (explored_leader_regions.size() < pessimistic_le_quorum_.size()) {
    PotentialNextLeaderResponse r =
        GetPotentialNextLeader(term_it, possible_leader_region);
    switch (r.status) {
      case PotentialNextLeaderResponse::POTENTIAL_NEXT_LEADER_DETECTED: {
        term_it = r.potential_leader_term;

        // Check next leader region to explore is within the list of regions
        // voters are present in for this replicaset.
        const std::map<std::string, std::string>::const_iterator
        uuid_to_region_it =
            uuid_to_region_.find(r.potential_leader_uuid);
        if (uuid_to_region_it == uuid_to_region_.end()) {
          // This should never happen, i.e. we are exploring a region which
          // is not in our configuration. In such a case, we return loss of
          // election.
          VLOG_WITH_PREFIX(1) << "Potential next leader: "
                              << r.potential_leader_uuid << " is not a part "
                              << "of the configuration.";
          return std::make_pair<>(false, false);
        } else {
          possible_leader_region = uuid_to_region_it->second;
        }
        explored_leader_regions.insert(possible_leader_region);
        VLOG_WITH_PREFIX(3)
            << "Potential next leader: "
            << r.potential_leader_uuid << " in region:  "
            << possible_leader_region
            << " detected with term: " << term_it;
        break;
      }
      case PotentialNextLeaderResponse::ALL_INTERMEDIATE_TERMS_DEFUNCT:
        VLOG_WITH_PREFIX(3)
            << "All intermediate terms since the last known leader: "
            << last_known_leader_.uuid << " in term: "
            << last_known_leader_.election_term << " are defunct. "
            << "Current election term: " << election_term_;
        return IsQuorumSatisfied(ResolveQuorum(possible_leader_region));
      case PotentialNextLeaderResponse::WAITING_FOR_MORE_VOTES:
      // TODO(ritwikyadav): Implement the case with only majority vote
      // as the requirement.
      default:
        VLOG_WITH_PREFIX(3)
            << "Waiting for more votes. Election result hasn't been "
            << "determined. Election term: " << election_term_;
        return std::make_pair<>(false, true);
    }
  }

  // Step 4: We have converged to the most pessimistic quorum which hasn't
  // been satisfied yet.
  return presult;
}

bool FlexibleVoteCounter::IsDecided() const {
  const std::pair<bool, bool> quorum_state = GetQuorumState();
  return quorum_state.first || !quorum_state.second;
}

Status FlexibleVoteCounter::GetDecision(ElectionVote* decision) const {
  const std::pair<bool, bool> quorum_state = GetQuorumState();
  if (quorum_state.first) {
    *decision = VOTE_GRANTED;
    return Status::OK();
  }
  if (!quorum_state.second) {
    *decision = VOTE_DENIED;
    return Status::OK();
  }
  return Status::IllegalState("Vote not yet decided");
}

std::string FlexibleVoteCounter::LogPrefix() const {
  return Substitute(
      "[Flexible Vote Counter] Election term: $0 "
      "Last known leader region: $1 ",
      election_term_, last_known_leader_region_);
}

///////////////////////////////////////////////////
// ElectionResult
///////////////////////////////////////////////////

ElectionResult::ElectionResult(VoteRequestPB vote_request, ElectionVote decision,
                               ConsensusTerm highest_voter_term, const std::string& message)
  : vote_request(std::move(vote_request)),
    decision(decision),
    highest_voter_term(highest_voter_term),
    message(message) {
  DCHECK(!message.empty());
}

///////////////////////////////////////////////////
// LeaderElection::VoterState
///////////////////////////////////////////////////

string LeaderElection::VoterState::PeerInfo() const {
  std::string info = peer_uuid;
  if (proxy) {
    strings::SubstituteAndAppend(&info, " ($0)", proxy->PeerName());
  }
  return info;
}

///////////////////////////////////////////////////
// LeaderElection
///////////////////////////////////////////////////

LeaderElection::LeaderElection(RaftConfigPB config,
                               PeerProxyFactory* proxy_factory,
                               VoteRequestPB request,
                               gscoped_ptr<VoteCounter> vote_counter,
                               MonoDelta timeout,
                               ElectionDecisionCallback decision_callback)
    : has_responded_(false),
      config_(std::move(config)),
      proxy_factory_(proxy_factory),
      request_(std::move(request)),
      vote_counter_(std::move(vote_counter)),
      timeout_(timeout),
      decision_callback_(std::move(decision_callback)),
      highest_voter_term_(0) {
}

LeaderElection::~LeaderElection() {
  std::lock_guard<Lock> guard(lock_);
  DCHECK(has_responded_); // We must always call the callback exactly once.
  STLDeleteValues(&voter_state_);
}

void LeaderElection::Run() {
  VLOG_WITH_PREFIX(1) << "Running leader election.";

  // Initialize voter state tracking.
  vector<string> other_voter_uuids;
  voter_state_.clear();
  for (const RaftPeerPB& peer : config_.peers()) {
    if (request_.candidate_uuid() == peer.permanent_uuid()) {
      DCHECK_EQ(peer.member_type(), RaftPeerPB::VOTER)
          << Substitute("non-voter member $0 tried to start an election; "
                        "Raft config {$1}",
                        peer.permanent_uuid(),
                        pb_util::SecureShortDebugString(config_));
      continue;
    }
    if (peer.member_type() != RaftPeerPB::VOTER) {
      continue;
    }
    other_voter_uuids.emplace_back(peer.permanent_uuid());

    gscoped_ptr<VoterState> state(new VoterState());
    state->peer_uuid = peer.permanent_uuid();
    state->proxy_status = proxy_factory_->NewProxy(peer, &state->proxy);
    InsertOrDie(&voter_state_, peer.permanent_uuid(), state.release());
  }

  // Ensure that the candidate has already voted for itself.
  CHECK_EQ(1, vote_counter_->GetTotalVotesCounted()) << "Candidate must vote for itself first";

  // Ensure that existing votes + future votes add up to the expected total.
  CHECK_EQ(vote_counter_->GetTotalVotesCounted() + other_voter_uuids.size(),
           vote_counter_->GetTotalExpectedVotes())
      << "Expected different number of voters. Voter UUIDs: ["
      << JoinStringsIterator(other_voter_uuids.begin(), other_voter_uuids.end(), ", ")
      << "]; RaftConfig: {" << pb_util::SecureShortDebugString(config_) << "}";

  // Check if we have already won the election (relevant if this is a
  // single-node configuration, since we always pre-vote for ourselves).
  CheckForDecision();

  // The rest of the code below is for a typical multi-node configuration.
  for (const auto& voter_uuid : other_voter_uuids) {
    VoterState* state = nullptr;
    {
      std::lock_guard<Lock> guard(lock_);
      state = FindOrDie(voter_state_, voter_uuid);
      // Safe to drop the lock because voter_state_ is not mutated outside of
      // the constructor / destructor. We do this to avoid deadlocks below.
    }

    // If we failed to construct the proxy, just record a 'NO' vote with the status
    // that indicates why it failed.
    if (!state->proxy_status.ok()) {
      LOG_WITH_PREFIX(WARNING) << "Was unable to construct an RPC proxy to peer "
                               << state->PeerInfo() << ": " << state->proxy_status.ToString()
                               << ". Counting it as a 'NO' vote.";
      {
        std::lock_guard<Lock> guard(lock_);
        RecordVoteUnlocked(*state, VOTE_DENIED);
      }
      CheckForDecision();
      continue;
    }

    // Send the RPC request.
    LOG_WITH_PREFIX(INFO) << "Requesting "
                          << (request_.is_pre_election() ? "pre-" : "")
                          << "vote from peer " << state->PeerInfo();
    state->rpc.set_timeout(timeout_);

    state->request = request_;
    state->request.set_dest_uuid(voter_uuid);

    state->proxy->RequestConsensusVoteAsync(
        &state->request,
        &state->response,
        &state->rpc,
        // We use gutil Bind() for the refcounting and boost::bind to adapt the
        // gutil Callback to a thunk.
        boost::bind(&Closure::Run,
                    Bind(&LeaderElection::VoteResponseRpcCallback, this, voter_uuid)));
  }
}

void LeaderElection::CheckForDecision() {
  bool to_respond = false;
  {
    std::lock_guard<Lock> guard(lock_);
    // Check if the vote has been newly decided.
    if (!result_ && vote_counter_->IsDecided()) {
      ElectionVote decision;
      CHECK_OK(vote_counter_->GetDecision(&decision));
      LOG_WITH_PREFIX(INFO) << "Election decided. Result: candidate "
                << ((decision == VOTE_GRANTED) ? "won." : "lost.");
      string msg = (decision == VOTE_GRANTED) ?
          "achieved majority votes" : "could not achieve majority";
      result_.reset(new ElectionResult(request_, decision, highest_voter_term_, msg));
    }
    // Check whether to respond. This can happen as a result of either getting
    // a majority vote or of something invalidating the election, like
    // observing a higher term.
    if (result_ && !has_responded_) {
      has_responded_ = true;
      to_respond = true;
    }
  }

  // Respond outside of the lock.
  if (to_respond) {
    // This is thread-safe since result_ is write-once.
    decision_callback_(*result_);
  }
}

void LeaderElection::VoteResponseRpcCallback(const std::string& voter_uuid) {
  {
    std::lock_guard<Lock> guard(lock_);
    VoterState* state = FindOrDie(voter_state_, voter_uuid);

    // Check for RPC errors.
    if (!state->rpc.status().ok()) {
      LOG_WITH_PREFIX(WARNING) << "RPC error from VoteRequest() call to peer "
                               << state->PeerInfo() << ": "
                               << state->rpc.status().ToString();
      RecordVoteUnlocked(*state, VOTE_DENIED);

    // Check for tablet errors.
    } else if (state->response.has_error()) {
#ifdef FB_DO_NOT_REMOVE
      LOG_WITH_PREFIX(WARNING) << "Tablet error from VoteRequest() call to peer "
                               << state->PeerInfo() << ": "
                               << StatusFromPB(state->response.error().status()).ToString();
#endif
      RecordVoteUnlocked(*state, VOTE_DENIED);

    // If the peer changed their IP address, we shouldn't count this vote since
    // our knowledge of the configuration is in an inconsistent state.
    } else if (PREDICT_FALSE(voter_uuid != state->response.responder_uuid())) {
      LOG_WITH_PREFIX(DFATAL) << "Received vote response from peer "
                              << state->PeerInfo() << ": "
                              << "we thought peer had UUID " << voter_uuid
                              << " but its actual UUID is "
                              << state->response.responder_uuid();
      RecordVoteUnlocked(*state, VOTE_DENIED);

    } else {
      // No error: count actual votes.
      highest_voter_term_ = std::max(highest_voter_term_, state->response.responder_term());
      if (state->response.vote_granted()) {
        HandleVoteGrantedUnlocked(*state);
      } else {
        HandleVoteDeniedUnlocked(*state);
      }
    }
  }

  // Check for a decision outside the lock.
  CheckForDecision();
}

void LeaderElection::RecordVoteUnlocked(
    const VoterState& state, ElectionVote vote) {
  DCHECK(lock_.is_locked());

  // Construct vote information struct.
  VoteInfo vote_info;
  vote_info.vote = vote;
  for (int i = 0; i < state.response.previous_vote_history_size(); i++) {
    vote_info.previous_vote_history.push_back(
        state.response.previous_vote_history(i));
  }

  // Sorting according to election_term.
  std::sort(
      vote_info.previous_vote_history.begin(),
      vote_info.previous_vote_history.end(),
      compare_PreviousVotePB);

  // Record the vote.
  bool duplicate;
  Status s = vote_counter_->RegisterVote(
      state.peer_uuid, vote_info, &duplicate);
  if (!s.ok()) {
    LOG_WITH_PREFIX(WARNING) << "Error registering vote for peer "
                             << state.PeerInfo() << ": " << s.ToString();
    return;
  }
  if (duplicate) {
    // Note: This is DFATAL because at the time of writing we do not support
    // retrying vote requests, so this should be impossible. It may be valid to
    // receive duplicate votes in the future if we implement retry.
    LOG_WITH_PREFIX(DFATAL) << "Duplicate vote received from peer " << state.PeerInfo();
  }
}

void LeaderElection::HandleHigherTermUnlocked(const VoterState& state) {
  DCHECK(lock_.is_locked());
  DCHECK_GT(state.response.responder_term(), election_term());

  string msg = Substitute("Vote denied by peer $0 with higher term. Message: $1",
                          state.PeerInfo(),
                          StatusFromPB(state.response.consensus_error().status()).ToString());
  LOG_WITH_PREFIX(WARNING) << msg;

  if (!result_) {
    LOG_WITH_PREFIX(INFO) << "Cancelling election due to peer responding with higher term";
    result_.reset(new ElectionResult(request_, VOTE_DENIED,
                                     state.response.responder_term(), msg));
  }
}

void LeaderElection::HandleVoteGrantedUnlocked(const VoterState& state) {
  DCHECK(lock_.is_locked());
  if (!request_.is_pre_election()) {
    DCHECK_EQ(state.response.responder_term(), election_term());
  }
  DCHECK(state.response.vote_granted());

  LOG_WITH_PREFIX(INFO) << "Vote granted by peer " << state.PeerInfo();
  RecordVoteUnlocked(state, VOTE_GRANTED);
}

void LeaderElection::HandleVoteDeniedUnlocked(const VoterState& state) {
  DCHECK(lock_.is_locked());
  DCHECK(!state.response.vote_granted());

  // If one of the voters responds with a greater term than our own, and we
  // have not yet triggered the decision callback, it cancels the election.
  if (state.response.responder_term() > election_term()) {
    return HandleHigherTermUnlocked(state);
  }

  LOG_WITH_PREFIX(INFO) << "Vote denied by peer " << state.PeerInfo() << ". Message: "
            << StatusFromPB(state.response.consensus_error().status()).ToString();
  RecordVoteUnlocked(state, VOTE_DENIED);
}

std::string LeaderElection::LogPrefix() const {
  return Substitute("T $0 P $1 [CANDIDATE]: Term $2 $3election: ",
                    request_.tablet_id(),
                    request_.candidate_uuid(),
                    request_.candidate_term(),
                    request_.is_pre_election() ? "pre-" : "");
}

} // namespace consensus
} // namespace kudu

max_stars_repo_name: iRitwik/kuduraft

max_issues_repo_name: iRitwik/kuduraft

max_forks_repo_name: iRitwik/kuduraft


text:
// Copyright Daniel Wallin 2007. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <cctype>
#include <iostream>

#include <libtorrent/extensions.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/peer_request.hpp>
#include <libtorrent/disk_buffer_holder.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

namespace
{
  struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
  {
      void add_handshake(entry& e)
      {
          if (override f = this->get_override("add_handshake"))
              e = call<entry>(f.ptr(), e);
          else
              peer_plugin::add_handshake(e);
      }

      void default_add_handshake(entry& e)
      {
          this->peer_plugin::add_handshake(e);
      }

      bool on_handshake(char const* reserved_bits)
      {
          if (override f = this->get_override("on_handshake"))
              return f();
          else
              return peer_plugin::on_handshake(reserved_bits);
      }

      bool default_on_handshake(char const* reserved_bits)
      {
          return this->peer_plugin::on_handshake(reserved_bits);
      }

      bool on_extension_handshake(lazy_entry const& e)
      {
          if (override f = this->get_override("on_extension_handshake"))
              return f(e);
          else
              return peer_plugin::on_extension_handshake(e);
      }

      bool default_on_extension_handshake(lazy_entry const& e)
      {
          return this->peer_plugin::on_extension_handshake(e);
      }

      bool on_choke()
      {
          if (override f = this->get_override("on_choke"))
              return f();
          else
              return peer_plugin::on_choke();
      }

      bool default_on_choke()
      {
          return this->peer_plugin::on_choke();
      }

      bool on_unchoke()
      {
          if (override f = this->get_override("on_unchoke"))
              return f();
          else
              return peer_plugin::on_unchoke();
      }

      bool default_on_unchoke()
      {
          return this->peer_plugin::on_unchoke();
      }

      bool on_interested()
      {
          if (override f = this->get_override("on_interested"))
              return f();
          else
              return peer_plugin::on_interested();
      }

      bool default_on_interested()
      {
          return this->peer_plugin::on_interested();
      }

      bool on_not_interested()
      {
          if (override f = this->get_override("on_not_interested"))
              return f();
          else
              return peer_plugin::on_not_interested();
      }

      bool default_on_not_interested()
      {
          return this->peer_plugin::on_not_interested();
      }

      bool on_have(int index)
      {
          if (override f = this->get_override("on_have"))
              return f(index);
          else
              return peer_plugin::on_have(index);
      }

      bool default_on_have(int index)
      {
          return this->peer_plugin::on_have(index);
      }

      bool on_bitfield(list _bf)
      {
          //Convert list to a bitfield
          bitfield bf(len(_bf));
          for (int i = 0; i < len(_bf); ++i)
          {
              if (_bf[i])
                  bf.set_bit(i);
              else
                  bf.clear_bit(i);
          }
          if (override f = this->get_override("on_bitfield"))
              return f(bf);
          else
              return peer_plugin::on_bitfield(bf);
      }

      bool default_on_bitfield(const bitfield &bf)
      {
          return this->peer_plugin::on_bitfield(bf);
      }

      bool on_request(peer_request const& req)
      {
          if (override f = this->get_override("on_request"))
              return f(req);
          else
              return peer_plugin::on_request(req);
      }

      bool default_on_request(peer_request const& req)
      {
          return this->peer_plugin::on_request(req);
      }

      bool on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          if (override f = this->get_override("on_piece"))
              return f(piece, data);
          else
              return peer_plugin::on_piece(piece, data);
      }

      bool default_on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          return this->peer_plugin::on_piece(piece, data);
      }

      bool on_cancel(peer_request const& req)
      {
          if (override f = this->get_override("on_cancel"))
              return f(req);
          else
              return peer_plugin::on_cancel(req);
      }

      bool default_on_cancel(peer_request const& req)
      {
          return this->peer_plugin::on_cancel(req);
      }

      bool on_extended(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_extended"))
              return f(length, msg, body);
          else
              return peer_plugin::on_extended(length, msg, body);
      }

      bool default_on_extended(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_extended(length, msg, body);
      }

      bool on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_unknown_message"))
              return f(length, msg, body);
          else
              return peer_plugin::on_unknown_message(length, msg, body);
      }

      bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_unknown_message(length, msg, body);
      }

      void on_piece_pass(int index)
      {
          if (override f = this->get_override("on_piece_pass"))
              f(index);
          else
              peer_plugin::on_piece_pass(index);
      }

      void default_on_piece_pass(int index)
      {
          this->peer_plugin::on_piece_pass(index);
      }

      void on_piece_failed(int index)
      {
          if (override f = this->get_override("on_piece_failed"))
              f(index);
          else
              peer_plugin::on_piece_failed(index);
      }

      void default_on_piece_failed(int index)
      {
          this->peer_plugin::on_piece_failed(index);
      }

      void tick()
      {
          if (override f = this->get_override("tick"))
              f();
          else
              peer_plugin::tick();
      }

      void default_tick()
      {
          this->peer_plugin::tick();
      }

      bool write_request(peer_request const& req)
      {
          if (override f = this->get_override("write_request"))
              return f(req);
          else
              return peer_plugin::write_request(req);
      }

      bool default_write_request(peer_request const& req)
      {
          return this->peer_plugin::write_request(req);
      }
  };

  object get_buffer()
  {
      static char const data[] = "foobar";
      return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
  }

} // namespace unnamed

void bind_peer_plugin()
{
    class_<
        peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
    >("peer_plugin")
        .def(
            "add_handshake"
          , &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
        )
        .def(
            "on_handshake"
          , &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
        )
        .def(
            "on_extension_handshake"
          , &peer_plugin::on_extension_handshake
          , &peer_plugin_wrap::default_on_extension_handshake
        )
        .def(
            "on_choke"
          , &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
        )
        .def(
            "on_unchoke"
          , &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
        )
        .def(
            "on_interested"
          , &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
        )
        .def(
            "on_not_interested"
          , &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
        )
        .def(
            "on_have"
          , &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
        )
        .def(
            "on_bitfield"
          , &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
        )
        .def(
            "on_request"
          , &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
        )
        .def(
            "on_piece"
          , &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
        )
        .def(
            "on_cancel"
          , &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
        )
        .def(
            "on_piece_pass"
          , &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
        )
        .def(
            "on_piece_failed"
          , &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
        )
        .def(
            "tick"
          , &peer_plugin::tick, &peer_plugin_wrap::default_tick
        )
        .def(
            "write_request"
          , &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
        )
        // These seem to make VC7.1 freeze. Needs special handling.

        /*.def(
            "on_extended"
          , &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
        )
        .def(
            "on_unknown_message"
          , &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
        )*/
        ;

    def("get_buffer", &get_buffer);
}

ext: cpp

max_stars_repo_name: CarysT/medusa

max_issues_repo_name: CarysT/medusa

max_forks_repo_name: CarysT/medusa


text:
// ====================================================================
// This file is part of FlexibleSUSY.
//
// FlexibleSUSY is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// FlexibleSUSY 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FlexibleSUSY.  If not, see
// <http://www.gnu.org/licenses/>.
// ====================================================================

#ifndef EIGEN_UTILS_H
#define EIGEN_UTILS_H

#include <Eigen/Core>
#include <cassert>
#include <complex>
#include <iomanip>
#include <sstream>
#include <string>
#include <limits>

namespace flexiblesusy {

template <typename Derived>
int closest_index(double mass, const Eigen::ArrayBase<Derived>& v)
{
   int pos;
   typename Derived::PlainObject tmp;
   tmp.setConstant(mass);

   (v - tmp).abs().minCoeff(&pos);

   return pos;
}

template <class BinaryOp, class Derived>
Derived binary_map(
   const Eigen::DenseBase<Derived>& a, const Eigen::DenseBase<Derived>& b, BinaryOp op)
{
   typename Derived::PlainObject result(a.rows(), b.cols());

   assert(a.rows() == b.rows());
   assert(a.cols() == b.cols());

   for (int k = 0; k < a.cols(); k++)
      for (int i = 0; i < a.rows(); i++)
         result(i,k) = op(a(i,k), b(i,k));

   return result;
}

/**
 * Divides a by b element wise.  If the quotient is not finite, it is
 * set to zero.
 *
 * @param a numerator
 * @param b denominator
 */
template <class Derived>
Derived div_safe(
   const Eigen::DenseBase<Derived>& a, const Eigen::DenseBase<Derived>& b)
{
   using Scalar = typename Derived::Scalar;

   return binary_map(a, b, [](Scalar x, Scalar y){
         const Scalar q = x / y;
         return std::isfinite(q) ? q : Scalar{};
      });
}

/**
 * Calls eval() on any Eigen expression.  If the argument is not an
 * Eigen expression, the argument is returned.
 *
 * @param expr expression
 *
 * @return evaluated expression or argument
 */
template <class Derived>
auto Eval(const Eigen::DenseBase<Derived>& expr) -> decltype(expr.eval())
{
   return expr.eval();
}

inline char                 Eval(char                        expr) { return expr; }
inline short                Eval(short                       expr) { return expr; }
inline int                  Eval(int                         expr) { return expr; }
inline long                 Eval(long                        expr) { return expr; }
inline unsigned short       Eval(unsigned short              expr) { return expr; }
inline unsigned int         Eval(unsigned int                expr) { return expr; }
inline unsigned long        Eval(unsigned long               expr) { return expr; }
inline double               Eval(double                      expr) { return expr; }
inline std::complex<double> Eval(const std::complex<double>& expr) { return expr; }

/**
 * The element of v, which is closest to mass, is moved to the
 * position idx.
 *
 * @param idx new index of the mass eigenvalue
 * @param mass mass to compare against
 * @param v vector of masses
 * @param z corresponding mixing matrix
 */
template <typename DerivedArray, typename DerivedMatrix>
void move_goldstone_to(int idx, double mass, Eigen::ArrayBase<DerivedArray>& v,
                       Eigen::MatrixBase<DerivedMatrix>& z)
{
   int pos = closest_index(mass, v);
   if (pos == idx)
      return;

   const int sign = (idx - pos) < 0 ? -1 : 1;
   int steps = std::abs(idx - pos);

   // now we shuffle the states
   while (steps--) {
      const int new_pos = pos + sign;
      v.row(new_pos).swap(v.row(pos));
      z.row(new_pos).swap(z.row(pos));
      pos = new_pos;
   }
}

/**
 * Normalize each element of the given real matrix to be within the
 * interval [min, max].  Values < min are set to min.  Values > max
 * are set to max.
 *
 * @param m matrix
 * @param min minimum
 * @param max maximum
 */
template <int M, int N>
void normalize_to_interval(Eigen::Matrix<double,M,N>& m, double min = -1., double max = 1.)
{
   auto data = m.data();
   const auto size = m.size();

   for (int i = 0; i < size; i++) {
      if (data[i] < min)
         data[i] = min;
      else if (data[i] > max)
         data[i] = max;
   }
}

/**
 * Normalize each element of the given complex matrix to have a
 * magnitude within the interval [0, max].  If the magnitude of a
 * matrix element is > max, then the magnitude is set to max.  The
 * phase angles are not modified.
 *
 * @param m matrix
 * @param max_mag maximum magnitude
 */
template <int M, int N>
void normalize_to_interval(Eigen::Matrix<std::complex<double>,M,N>& m, double max_mag = 1.)
{
   auto data = m.data();
   const auto size = m.size();

   for (int i = 0; i < size; i++) {
      if (std::abs(data[i]) > max_mag)
         data[i] = std::polar(max_mag, std::arg(data[i]));
   }
}

namespace {
template <class T>
struct Is_not_finite {
   bool operator()(T x) const noexcept { return !std::isfinite(x); }
};
} // anonymous namespace

/**
 * Returns all elements from src, which are not close to the elements
 * in cmp.  The returned vector will have the length (src.size() -
 * cmp.size()).
 *
 * @param src source vector
 * @param cmp vector with elements to compare against
 * @return vector with elements of src not close to cmp
 */
template<class Real, int Nsrc, int Ncmp>
Eigen::Array<Real,Nsrc - Ncmp,1> remove_if_equal(
   const Eigen::Array<Real,Nsrc,1>& src,
   const Eigen::Array<Real,Ncmp,1>& cmp)
{
   Eigen::Array<Real,Nsrc,1> non_equal(src);
   Eigen::Array<Real,Nsrc - Ncmp,1> dst;

   for (int i = 0; i < Ncmp; i++) {
      const int idx = closest_index(cmp(i), non_equal);
      non_equal(idx) = std::numeric_limits<double>::infinity();
   }

   std::remove_copy_if(non_equal.data(), non_equal.data() + Nsrc,
                       dst.data(), Is_not_finite<Real>());

   return dst;
}

/**
 * @brief reorders vector v according to ordering in vector v2
 * @param v vector with elementes to be reordered
 * @param v2 vector with reference ordering
 */
template<class Real, int N>
void reorder_vector(
   Eigen::Array<Real,N,1>& v,
   const Eigen::Array<Real,N,1>& v2)
{
   Eigen::PermutationMatrix<N> p;
   p.setIdentity();
   std::sort(p.indices().data(), p.indices().data() + p.indices().size(),
             [&v2] (int i, int j) { return v2[i] < v2[j]; });

#if EIGEN_VERSION_AT_LEAST(3,1,4)
   v.matrix().transpose() *= p.inverse();
#else
   Eigen::Map<Eigen::Matrix<Real,N,1> >(v.data()).transpose() *= p.inverse();
#endif
}

/**
 * @brief reorders vector v according to ordering of diagonal elements in mass_matrix
 * @param v vector with elementes to be reordered
 * @param matrix matrix with diagonal elements with reference ordering
 */
template<class Derived>
void reorder_vector(
   Eigen::Array<double,Eigen::MatrixBase<Derived>::RowsAtCompileTime,1>& v,
   const Eigen::MatrixBase<Derived>& matrix)
{
   reorder_vector(v, matrix.diagonal().array().eval());
}

template<class Derived>
std::string print_scientific(const Eigen::DenseBase<Derived>& v,
                             int number_of_digits = std::numeric_limits<typename Derived::Scalar>::digits10 + 1)
{
   std::ostringstream sstr;

   for (int k = 0; k < v.cols(); k++) {
      for (int i = 0; i < v.rows(); i++) {
         sstr << std::setprecision(number_of_digits)
              << std::scientific << v(i,k) << ' ';
      }
      sstr << '\n';
   }

   return sstr.str();
}

} // namespace flexiblesusy

#endif

ext: hpp


text:
#include <fstream>
#include <cal.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

int main() {
    // Testing driver code below
    using namespace std;
    vector<ical::event> lists;
    ical::event EVENT;

    /*
    for (size_t i = 0; i < 5; i++) {
        EVENT.subjectName = to_string(i);
        lists.push_back(EVENT);
    }
    ofstream ofs("../test");

    ical::saveEvent(lists, ofs);
    */

    ifstream ifs("../test");

    ical::loadEvent(lists, ifs);

    for (size_t i = 0; i < lists.size(); i++) {
        cout << lists[i].name << " ";
    }

    return 0;
}

max_stars_repo_name: ChayanonPitak/Uics

max_issues_repo_name: ChayanonPitak/Uics

max_forks_repo_name: ChayanonPitak/Uics


text:
// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/assert.hpp>
#include <boost/hana/chain.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/tap.hpp>
#include <boost/hana/tuple.hpp>

#include <set>
namespace hana = boost::hana;

int main() {
    // We use a sorted container because the order in which the functions
    // are called is unspecified.
    std::set<int> before, after;

    auto xs = hana::make_tuple(1, 2, 3)
        | hana::tap<hana::tuple_tag>([&](int x) { before.insert(x); })
        | [](auto x) { return hana::make_tuple(x, -x); }
        | hana::tap<hana::tuple_tag>([&](int x) { after.insert(x); });

    BOOST_HANA_RUNTIME_CHECK(before == std::set<int>{1, 2, 3});
    BOOST_HANA_RUNTIME_CHECK(after == std::set<int>{1, -1, 2, -2, 3, -3});
    BOOST_HANA_RUNTIME_CHECK(xs == hana::make_tuple(1, -1, 2, -2, 3, -3));
}

max_stars_repo_name: nxplatform/nx-mobile

max_issues_repo_name: nxplatform/nx-mobile

max_forks_repo_name: nxplatform/nx-mobile


text:
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#if !defined(BOOST_UNORDERED_TEST_TEST_HEADER)
#define BOOST_UNORDERED_TEST_TEST_HEADER

#include <boost/detail/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>

#define UNORDERED_AUTO_TEST(x)                                                 \
    struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base        \
    {                                                                          \
        BOOST_PP_CAT(x, _type)                                                 \
        () : ::test::registered_test_base(BOOST_PP_STRINGIZE(x))               \
        {                                                                      \
            ::test::test_list::add_test(this);                                 \
        }                                                                      \
        void run();                                                            \
    };                                                                         \
    BOOST_PP_CAT(x, _type) x;                                                  \
    void BOOST_PP_CAT(x, _type)::run()

#define RUN_TESTS()                                                            \
    int main(int, char**)                                                      \
    {                                                                          \
        ::test::write_compiler_info();                                         \
        ::test::test_list::run_tests();                                        \
        return boost::report_errors();                                         \
    }

namespace test {
struct registered_test_base
{
    registered_test_base* next;
    char const* name;
    explicit registered_test_base(char const* n) : name(n) {}
    virtual void run() = 0;
    virtual ~registered_test_base() {}
};

namespace test_list {
static inline registered_test_base*& first()
{
    static registered_test_base* ptr = 0;
    return ptr;
}

static inline registered_test_base*& last()
{
    static registered_test_base* ptr = 0;
    return ptr;
}

static inline void add_test(registered_test_base* test)
{
    if (last()) {
        last()->next = test;
    } else {
        first() = test;
    }

    last() = test;
}

static inline void run_tests()
{
    for (registered_test_base* i = first(); i; i = i->next) {
        std::cout << "Running " << i->name << "\n" << std::flush;
        i->run();
        std::cerr << std::flush;
        std::cout << std::flush;
    }
}
}

inline void write_compiler_info()
{
#if defined(BOOST_GCC_CXX11)
    char const* cpp11 = "true";
#else
    char const* cpp11 = "false";
#endif

    std::cout << "Compiler: " << BOOST_COMPILER << "\n"
              << "Library: " << BOOST_STDLIB << "\n"
              << "C++11: " << cpp11 << "\n"
              << "\n"
              << std::flush;
}
}

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>

// Run test with every combination of the parameters (a sequence of sequences)
#define UNORDERED_TEST(name, parameters)                                       \
    BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((1))parameters)

#define UNORDERED_TEST_REPEAT(name, n, parameters)                             \
    BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((n))parameters)

#define UNORDERED_TEST_OP(r, product)                                          \
    UNORDERED_TEST_OP2(BOOST_PP_SEQ_ELEM(0, product),                          \
        BOOST_PP_SEQ_ELEM(1, product),                                         \
        BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_TAIL(product)))

#define UNORDERED_TEST_OP2(name, n, params)                                    \
    UNORDERED_AUTO_TEST(                                                       \
        BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params))          \
    {                                                                          \
        for (int i = 0; i < n; ++i)                                            \
            name BOOST_PP_SEQ_TO_TUPLE(params);                                \
    }

#define UNORDERED_TEST_OP_JOIN(s, state, elem)                                 \
    BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))

#endif

max_stars_repo_name: lijgame/boost

max_issues_repo_name: lijgame/boost

max_forks_repo_name: lijgame/boost


text:
//==================================================================================================
/*!
  @file

    @copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_ATAN2PI_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_ATAN2PI_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

  /*!
    @ingroup group-trigonometric
    This function object returns the atan2pi function : atan2 in pi multiples.

    @par Header <boost/simd/function/atan2pi.hpp>

    @par Note

      For every parameters of same floating type `atan2pi(y, x)`
      is similar  to: `atan2(y, x)/Pi`

    @see atan2,  atan2pi

    @par Example:

      @snippet atan2pi.cpp atan2pi

    @par Possible output:

      @snippet atan2pi.txt atan2pi

  **/
  IEEEValue atan2pi(IEEEValue const& y, const IEEEValue& x);
} }
#endif

#include <boost/simd/function/scalar/atan2pi.hpp>
#include <boost/simd/function/simd/atan2pi.hpp>

#endif

max_stars_repo_name: SylvainCorlay/pythran

max_issues_repo_name: SylvainCorlay/pythran

max_forks_repo_name: SylvainCorlay/pythran


text:
#include <gtest/gtest.h>
#include <boost/range/algorithm/for_each.hpp>
#include "../src/shuffled_range.h"
#include <set>

TEST(ShuffleTest, Elements)
{
    ann::ShuffledRange range(123);

    std::set<size_t> elementCheck;

    for (int i=0; range.hasMoreElements(); ++i)
    {
        auto newRange = range.getNextN(10);
        ASSERT_TRUE(newRange.size() <= 10);
        boost::for_each(newRange, [&elementCheck](size_t value) {
            ASSERT_TRUE(elementCheck.count(value) == 0);
            elementCheck.insert(value);
        });
    }

    for (int i=0; i<123; i++)
    {
        ASSERT_TRUE(elementCheck.count(i) == 1);
    }
    ASSERT_FALSE(elementCheck.count(123) == 1);
}


text:
/* vim:set ts=3 sw=3 sts=3 et: */
/**
 * Copyright © 2008-2013 Last.fm Limited
 *
 * This file is part of libmoost.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/lexical_cast.hpp>

#include <map>
#include <string>

#include "../../include/moost/testing/test_directory_creator.hpp"

// to be changed to <moost/xml/simple_parser.hpp>!!!
#include "../../include/moost/xml/simple_parser.hpp"

using namespace moost;
using namespace moost::xml;

// -----------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE( simple_parser_test )

#define TESTPATH "SimpleParserTest_Directory"

struct Fixture
{

   Fixture()
   : m_tdc(TESTPATH)
   {
   }
   ~Fixture()
   {
   }

   moost::testing::test_directory_creator m_tdc;
   simple_parser m_parser;
};

// -----------------------------------------------------------------------------

namespace
{

   char const NO_CHILDREN_XML[] = {
      "<base>\n"
      "  <foo>1</foo>\n"
      "  <bar>2</bar>\n"
      "</base>\n"
   };

   char const ONE_LEVEL_CHILD_XML[] = {
      "<base>\n"
      "  <node>\n"
      "    <foo>1</foo>\n"
      "    <bar>2</bar>\n"
      "  </node>\n"
      "  <node>\n"
      "    <foo>3</foo>\n"
      "    <bar>4</bar>\n"
      "  </node>\n"
      "</base>\n"
   };

   char const NOT_CLOSED_TAG_XML[] = {
      "<base>\n"
      "  <node>\n"
      "    <foo>1\n"  // here!
      "    <bar>2</bar>\n"
      "  </node>\n"
      "</base>\n"
   };

   char const CLOSING_SLASH_MISSING_XML[] = {
      "<base>\n"
      "  <node>\n"
      "    <foo>1<foo>\n" // here
      "    <bar>2</bar>\n"
      "  </node>\n"
      "</base>\n"
   };

   char const WRONG_CLOSING_TAG_XML[] = {
      "<base>\n"
      "  <node>\n"
      "    <foo>1</somethingelse>\n" // here
      "    <bar>2</bar>\n"
      "  </node>\n"
      "</base>\n"
   };

   char const COMMENT_XML[] = {
      "<base>\n"
      "  <node>\n"
      "    <foo>1</foo>\n" // here
      "   <!-- <bar>2</bar> \n"
      "      hello hello\n"
      "      <commented_out>10</commented_out>\n"
      "  end of commend here -->\n"
      "  </node>\n"
      "</base>\n"
   };

   char const TO_LOWERCASE_XML[] = {
      "<BASE>\n"
      "  <FOO>one</FOO>\n"
      "  <BAR>two</BAR>\n"
      "</BASE>\n"
   };
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_file_not_found, Fixture )
{
   BOOST_CHECK_THROW( m_parser.load("unexisting_file.xml"), std::exception );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_no_children, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_no_children.xml");
   std::string sCfg(NO_CHILDREN_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename);
   const simple_parser::tree_branch_t& root = m_parser.get_root();

   BOOST_REQUIRE( root.size() == 1 ); // the head

   BOOST_CHECK_EQUAL( root.front()->header, "base" );

   simple_parser::tree_branch_t& leaves = root.front()->leaves;

   //std::vector<simple_parser::tree_node*>& leaves = root.front()->leaves;
   BOOST_REQUIRE( leaves.size() == 2 ); // must contain foo and bar

   BOOST_CHECK_EQUAL( leaves[0]->header, "foo" );
   BOOST_CHECK_EQUAL( leaves[0]->value, "1" );
   BOOST_CHECK( leaves[0]->leaves.empty() );

   BOOST_CHECK_EQUAL( leaves[1]->header, "bar" );
   BOOST_CHECK_EQUAL( leaves[1]->value, "2" );
   BOOST_CHECK( leaves[1]->leaves.empty() );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_one_level_child, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_one_level.xml");
   std::string sCfg(ONE_LEVEL_CHILD_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename);
   const simple_parser::tree_branch_t& root = m_parser.get_root();

   BOOST_REQUIRE( root.size() == 1 ); // the head
   BOOST_CHECK_EQUAL( root.front()->header, "base" );

   simple_parser::tree_branch_t& nodes = root.front()->leaves;
   BOOST_REQUIRE( nodes.size() == 2 ); // must contain two nodes

   BOOST_CHECK_EQUAL( nodes[0]->header, "node" );
   BOOST_CHECK( nodes[0]->value.empty() );
   BOOST_CHECK_EQUAL( nodes[1]->header, "node" );
   BOOST_CHECK( nodes[1]->value.empty() );

   for ( int i = 0; i < 2; ++i )
   {
      simple_parser::tree_branch_t& node_leaves = nodes[i]->leaves;
      BOOST_CHECK_EQUAL( node_leaves[0]->header, "foo" );
      BOOST_CHECK_EQUAL( node_leaves[0]->value, boost::lexical_cast<std::string>(2*i + 1) );
      BOOST_CHECK( node_leaves[0]->leaves.empty() );

      BOOST_CHECK_EQUAL( node_leaves[1]->header, "bar" );
      BOOST_CHECK_EQUAL( node_leaves[1]->value, boost::lexical_cast<std::string>(2*i + 2) );
      BOOST_CHECK( node_leaves[1]->leaves.empty() );
   }
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_no_closed_tags, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_no_closed_tags.xml");
   std::string sCfg(NOT_CLOSED_TAG_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   BOOST_CHECK_THROW( m_parser.load(sProxyFilename), std::exception );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_slash_missing, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_slash_missing.xml");
   std::string sCfg(CLOSING_SLASH_MISSING_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   BOOST_CHECK_THROW( m_parser.load(sProxyFilename), std::exception );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_wrong_closing, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_wrong_closing.xml");
   std::string sCfg(WRONG_CLOSING_TAG_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   BOOST_CHECK_THROW( m_parser.load(sProxyFilename), std::exception );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_comment, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("test_comment.xml");
   std::string sCfg(COMMENT_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename);
   const simple_parser::tree_branch_t& root = m_parser.get_root();

   BOOST_REQUIRE( root.size() == 1 ); // the head
   BOOST_CHECK_EQUAL( root.front()->header, "base" );

   simple_parser::tree_branch_t& nodes = root.front()->leaves;
   BOOST_REQUIRE( nodes.size() == 1 ); // must contain one node

   BOOST_CHECK_EQUAL( nodes[0]->header, "node" );
   BOOST_CHECK( nodes[0]->value.empty() );

   simple_parser::tree_branch_t& node_leaves = nodes[0]->leaves;
   BOOST_CHECK_EQUAL( node_leaves[0]->header, "foo" );
   BOOST_CHECK_EQUAL( node_leaves[0]->value, "1" );
   BOOST_CHECK( node_leaves[0]->leaves.empty() );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_to_lowercase_1, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_to_lowercase_1.xml");
   std::string sCfg(TO_LOWERCASE_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename);

   const simple_parser::tree_branch_t& root = m_parser.get_root();

   BOOST_REQUIRE( root.size() == 1 ); // the head
   BOOST_CHECK_EQUAL( root.front()->header, "BASE" );

   simple_parser::tree_branch_t& leaves = root.front()->leaves;
   BOOST_REQUIRE( leaves.size() == 2 ); // must contain foo and bar

   BOOST_CHECK_EQUAL( leaves[0]->header, "FOO" );
   BOOST_CHECK_EQUAL( leaves[0]->value, "one" );
   BOOST_CHECK_EQUAL( leaves[1]->header, "BAR" );
   BOOST_CHECK_EQUAL( leaves[1]->value, "two" );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_to_lowercase_2, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_to_lowercase_2.xml");
   std::string sCfg(TO_LOWERCASE_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename, true);

   const simple_parser::tree_branch_t& root = m_parser.get_root();

   BOOST_REQUIRE( root.size() == 1 ); // the head
   BOOST_CHECK_EQUAL( root.front()->header, "base" );

   simple_parser::tree_branch_t& leaves = root.front()->leaves;
   BOOST_REQUIRE( leaves.size() == 2 ); // must contain foo and bar

   BOOST_CHECK_EQUAL( leaves[0]->header, "foo" );
   BOOST_CHECK_EQUAL( leaves[0]->value, "one" );
   BOOST_CHECK_EQUAL( leaves[1]->header, "bar" );
   BOOST_CHECK_EQUAL( leaves[1]->value, "two" );
}

// -----------------------------------------------------------------------------

BOOST_FIXTURE_TEST_CASE( test_fill_from_branch, Fixture )
{
   std::string const& sProxyFilename = m_tdc.GetFilePath("parser_test_fill_from_branch.xml");
   std::string sCfg(NO_CHILDREN_XML);
   {
      std::ofstream ofs(sProxyFilename.c_str());
      ofs << sCfg;
   }

   m_parser.load(sProxyFilename);
   const simple_parser::tree_branch_t& root = m_parser.get_root();

   std::map<std::string, std::string> localMap;
   root.front()->leaves2map(localMap);

   BOOST_CHECK_EQUAL( localMap.size(), 2 );
   BOOST_CHECK_EQUAL( localMap["foo"], "1" );
   BOOST_CHECK_EQUAL( localMap["bar"], "2" );
}

// -----------------------------------------------------------------------------

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: lastfm/libmoost

max_issues_repo_name: lastfm/libmoost

max_forks_repo_name: lastfm/libmoost


text:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/detail/preprocessed/template_arity_helper.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/template_arity_helper.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    // template_arity_helper.hpp
    // Overloads of template_arity_helper, used by the template_arity\<\> class template
    //
    //  Copyright 2008 Eric Niebler. Distributed under the Boost
    //  Software License, Version 1.0. (See accompanying file
    //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/template_arity_helper.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

#else

    #define N BOOST_PP_ITERATION()

    template<
        template<BOOST_PP_ENUM_PARAMS(N, typename P)> class F
      , BOOST_PP_ENUM_PARAMS(N, typename T)
    >
    sized_type<BOOST_PP_INC(N)>::type
    template_arity_helper(F<BOOST_PP_ENUM_PARAMS(N, T)> **, mpl::int_<N> *);

    #undef N

#endif // BOOST_PROTO_DONT_USE_PREPROCESSED_FILES

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


text:
/*
 *          Copyright Andrey Semashev 2007 - 2014.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   main.cpp
 * \author Andrey Semashev
 * \date   26.04.2008
 *
 * \brief  An example of initializing the library from a settings file.
 *         See the library tutorial for expanded comments on this code.
 *         It may also be worthwhile reading the Wiki requirements page:
 *         http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost.Logging
 */

// #define BOOST_ALL_DYN_LINK 1

#include <exception>
#include <string>
#include <iostream>
#include <fstream>

#include <boost/log/common.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/from_stream.hpp>

namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;

using boost::shared_ptr;

// Here we define our application severity levels.
enum severity_level
{
    normal,
    notification,
    warning,
    error,
    critical
};

//  Global logger declaration
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(test_lg, src::severity_logger< >)

void try_logging()
{
    src::severity_logger< >& lg = test_lg::get();
    BOOST_LOG_SEV(lg, normal) << "This is a normal severity record";
    BOOST_LOG_SEV(lg, notification) << "This is a notification severity record";
    BOOST_LOG_SEV(lg, warning) << "This is a warning severity record";
    BOOST_LOG_SEV(lg, error) << "This is a error severity record";
    BOOST_LOG_SEV(lg, critical) << "This is a critical severity record";
}

int main(int argc, char* argv[])
{
    try
    {
        // Open the file
        std::ifstream settings("settings.txt");
        if (!settings.is_open())
        {
            std::cout << "Could not open settings.txt file" << std::endl;
            return 1;
        }

        // Read the settings and initialize logging library
        logging::init_from_stream(settings);

        // Add some attributes
        logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());

        // Try logging
        try_logging();

        // Now enable tagging and try again
        BOOST_LOG_SCOPED_THREAD_TAG("Tag", "TAGGED");
        try_logging();

        return 0;
    }
    catch (std::exception& e)
    {
        std::cout << "FAILURE: " << e.what() << std::endl;
        return 1;
    }
}

max_stars_repo_name: MisterTea/HyperNEAT


text:
/*
 * Copyright 2021 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <SPL/Core/CompilerException.h>
#include <SPL/Core/ToolkitModelImpl.h>
#include <UTILS/DistilleryApplication.h>

#include <fstream>
#include <boost/filesystem/path.hpp>
#include <string>

using namespace std;
using namespace std::tr1;
using namespace SPL;
using namespace SPL::Toolkit;

class ToolkitModelTest : public UTILS_NAMESPACE::DistilleryApplication
{
  public:
    ToolkitModelTest() {}

    void getArguments(option_vector_t& options)
    {
        setKeepRemainingArguments();
        option_t args[] = {
            { 'i', "input-file", ARG, "", ".xml input file", STR_OPT(ToolkitModelTest::setFilename),
              0, 0 },
        };
        APPEND_OPTIONS(options, args);
    }
    void setFilename(const option_t* /*option*/, const char* value) { fileName_ = value; }
    virtual int run(const std::vector<std::string>& /*remains*/)
    {
        auto_ptr<toolkitModelType> rawModel;
        ifstream istr(fileName_.c_str(), fstream::in);
        if (!istr) {
            cerr << "ERROR: Cannot open file '" << fileName_ << "'" << endl;
            exit(EXIT_FAILURE);
        }
        try {
            string buildDir(_argv_0);
            string::size_type pos = buildDir.rfind("/.libs");
            if (pos != string::npos)
                buildDir.erase(pos);
            else
                buildDir.erase(buildDir.rfind("/"));
            ::xml_schema::properties props;
            props.schema_location("http://www.ibm.com/xmlns/prod/streams/spl/toolkit",
                                  buildDir + "/../schema/xsd/toolkitModel.xsd");
            rawModel = toolkitModel(istr, 0, props);
            // rawModel = operatorModel(istr, xsd::cxx::tree::flags::dont_validate);
        } catch (::xsd::cxx::exception& e) {
            cerr << "ERROR: Cannot load xml model '" << fileName_ << "'" << endl;
            cerr << "ERROR: " << e.what() << endl;
            exit(EXIT_FAILURE);
        }
        auto_ptr<ToolkitModel> model;
        try {
            model.reset(new ToolkitModel(*rawModel));
        } catch (SPLCompilerException& e) {
            cerr << "ERROR: " << e.getExplanation() << endl;
            exit(EXIT_FAILURE);
        }
        printModel(*model);
        return 0;
    }
    void printModel(const ToolkitModel& model)
    {
        cout << "Description: " << model.getDescription() << "\n";
        cout << "Version: " << model.getVersion() << "\n";
        cout << "RequiredCompilerVersion: " << model.getRequiredCompilerVersion() << "\n";
        const unordered_map<string, NamespacePtr>& namespaces = model.getNamespaces();
        cout << "Namespaces: " << namespaces.size() << "\n";
        for (unordered_map<string, NamespacePtr>::const_iterator it = namespaces.begin();
             it != namespaces.end(); ++it) {
            printNamespace(*it->second);
        }
    }
    void printNamespace(const Namespace& nmspace)
    {
        cout << "  Namespace: " << nmspace.getName() << "\n";
        const unordered_map<string, PrimitiveOperatorPtr>& nopers = nmspace.getPrimitiveOperators();
        cout << "    Primitive operators: " << nopers.size() << "\n";
        for (unordered_map<string, PrimitiveOperatorPtr>::const_iterator it = nopers.begin();
             it != nopers.end(); ++it) {
            printPrimitiveOperator(*it->second);
        }
        const unordered_map<string, CompositeOperatorPtr>& copers = nmspace.getCompositeOperators();
        cout << "    Composite operators: " << copers.size() << "\n";
        for (unordered_map<string, CompositeOperatorPtr>::const_iterator it = copers.begin();
             it != copers.end(); ++it) {
            printCompositeOperator(*it->second);
        }
        const unordered_set<string>& sfuncs = nmspace.getSPLFunctionModelFiles();
        cout << "    SPL function model files: " << sfuncs.size() << "\n";
        for (unordered_set<string>::const_iterator it = sfuncs.begin(); it != sfuncs.end(); ++it) {
            cout << "      File: " << *it << "\n";
        }
        const unordered_set<string>& nfuncs = nmspace.getNativeFunctionModelFiles();
        cout << "    Native function model files: " << nfuncs.size() << "\n";
        for (unordered_set<string>::const_iterator it = nfuncs.begin(); it != nfuncs.end(); ++it) {
            cout << "      File: " << *it << "\n";
        }
    }
    void printOperator(const Operator& oper)
    {
        cout << "      Operator: " << oper.getName() << "\n";
        cout << "        Path: " << oper.getPath() << "\n";
        cout << "        Namespace (parent): " << oper.getNamespace().getName() << "\n";
    }
    void printPrimitiveOperator(const PrimitiveOperator& noper) { printOperator(noper); }
    void printCompositeOperator(const CompositeOperator& coper) { printOperator(coper); }

  private:
    string fileName_;
};

MAIN_APP(ToolkitModelTest)

max_stars_repo_name: IBMStreams/OSStreams

max_issues_repo_name: xguerin/openstreams

max_forks_repo_name: IBMStreams/OSStreams


text:
// Copyright 2012 Cloudera Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/cpu-info.h"
#include "util/debug-util.h"

#include <boost/algorithm/string.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

using namespace boost;
using namespace std;

namespace impala {

bool CpuInfo::initialized_ = false;
int64_t CpuInfo::hardware_flags_ = 0;
int64_t CpuInfo::original_hardware_flags_;
long CpuInfo::cache_sizes_[L3_CACHE + 1];
int64_t CpuInfo::cycles_per_ms_;
int CpuInfo::num_cores_ = 1;

static struct {
  string name;
  int64_t flag;
} flag_mappings[] =
{
  { "ssse3",  CpuInfo::SSE3 },
  { "sse4_1", CpuInfo::SSE4_1 },
  { "sse4_2", CpuInfo::SSE4_2 },
};
static const long num_flags = sizeof(flag_mappings) / sizeof(flag_mappings[0]);

// Helper function to parse for hardware flags.
// values contains a list of space-seperated flags.  check to see if the flags we
// care about are present.
// Returns a bitmap of flags.
int64_t ParseCPUFlags(const string& values) {
  int64_t flags = 0;
  for (int i = 0; i < num_flags; ++i) {
    if (contains(values, flag_mappings[i].name)) {
      flags |= flag_mappings[i].flag;
    }
  }
  return flags;
}

void CpuInfo::Init() {
  string line;
  string name;
  string value;

  float max_mhz = 0;
  int num_cores = 0;

  memset(&cache_sizes_, 0, sizeof(cache_sizes_));

  // Read from /proc/cpuinfo
  ifstream cpuinfo("/proc/cpuinfo", ios::in);
  while (cpuinfo) {
    getline(cpuinfo, line);
    size_t colon = line.find(':');
    if (colon != string::npos) {
      name = line.substr(0, colon - 1);
      value = line.substr(colon + 1, string::npos);
      trim(name);
      if (name.compare("flags") == 0) {
        trim(value);
        hardware_flags_ |= ParseCPUFlags(value);
      } else if (name.compare("cpu MHz") == 0) {
        trim(value);
        // Every core will report a different speed.  We'll take the max, assuming
        // that when impala is running, the core will not be in a lower power state.
        // TODO: is there a more robust way to do this, such as
        // Window's QueryPerformanceFrequency()
        float mhz = atof(value.c_str());
        max_mhz = max(mhz, max_mhz);
      } else if (name.compare("processor") == 0) {
        ++num_cores;
      }
    }
  }
  if (cpuinfo.is_open()) cpuinfo.close();

  // Call sysconf to query for the cache sizes
  cache_sizes_[0] = sysconf(_SC_LEVEL1_DCACHE_SIZE);
  cache_sizes_[1] = sysconf(_SC_LEVEL2_CACHE_SIZE);
  cache_sizes_[2] = sysconf(_SC_LEVEL3_CACHE_SIZE);

  if (max_mhz != 0) {
    cycles_per_ms_ = max_mhz * 1000;
  } else {
    cycles_per_ms_ = 1000000;
  }
  original_hardware_flags_ = hardware_flags_;

  if (num_cores > 0) {
    num_cores_ = num_cores;
  } else {
    num_cores_ = 1;
  }

  initialized_ = true;
  LOG(INFO) << DebugString();
}

void CpuInfo::EnableFeature(long flag, bool enable) {
  DCHECK(initialized_);
  if (!enable) {
    hardware_flags_ &= ~flag;
  } else {
    // Can't turn something on that can't be supported
    DCHECK((original_hardware_flags_ & flag) != 0);
    hardware_flags_ |= flag;
  }
}

string CpuInfo::DebugString() {
  DCHECK(initialized_);
  stringstream stream;
  int64_t L1 = CacheSize(L1_CACHE);
  int64_t L2 = CacheSize(L2_CACHE);
  int64_t L3 = CacheSize(L3_CACHE);
  stream << "Cpu Info:" << endl
         << "  Cores: " << num_cores_ << endl
         << "  L1 Cache: " << PrettyPrinter::Print(L1, TCounterType::BYTES) << endl
         << "  L2 Cache: " << PrettyPrinter::Print(L2, TCounterType::BYTES) << endl
         << "  L3 Cache: " << PrettyPrinter::Print(L3, TCounterType::BYTES) << endl
         << "  Hardware Supports:" << endl;
  for (int i = 0; i < num_flags; ++i) {
    if (IsSupported(flag_mappings[i].flag)) {
      stream << "    " << flag_mappings[i].name << endl;
    }
  }
  return stream.str();
}

}

ext: cc

max_stars_repo_name: hyphaltip/impala

max_issues_repo_name: hyphaltip/impala

max_forks_repo_name: hyphaltip/impala


text:
#pragma once

#include <boost/container/flat_set.hpp>
namespace crow
{
namespace webroutes
{

static boost::container::flat_set<std::string> routes;

} // namespace webroutes

} // namespace crow

max_stars_repo_name: sbteeks/bmcweb

max_issues_repo_name: sbteeks/bmcweb

max_forks_repo_name: sbteeks/bmcweb


text:
/**
 * Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
 * http://soramitsu.co.jp
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IROHA_SHARED_MODEL_PROTO_ACCOUNT_RESPONSE_HPP
#define IROHA_SHARED_MODEL_PROTO_ACCOUNT_RESPONSE_HPP

#include <boost/range/numeric.hpp>

#include "backend/protobuf/common_objects/account.hpp"
#include "backend/protobuf/common_objects/trivial_proto.hpp"
#include "interfaces/query_responses/account_response.hpp"
#include "qry_responses.pb.h"
#include "utils/lazy_initializer.hpp"

namespace shared_model {
  namespace proto {
    class AccountResponse final
        : public CopyableProto<interface::AccountResponse,
                               iroha::protocol::QueryResponse,
                               AccountResponse> {
     public:
      template <typename QueryResponseType>
      explicit AccountResponse(QueryResponseType &&queryResponse);

      AccountResponse(const AccountResponse &o);

      AccountResponse(AccountResponse &&o);

      const interface::Account &account() const override;

      const AccountRolesIdType &roles() const override;

     private:
      template <typename T>
      using Lazy = detail::LazyInitializer<T>;

      const iroha::protocol::AccountResponse &accountResponse_;

      const Lazy<AccountRolesIdType> accountRoles_;

      const Lazy<shared_model::proto::Account> account_;
    };
  }  // namespace proto
}  // namespace shared_model

#endif  // IROHA_SHARED_MODEL_PROTO_ACCOUNT_RESPONSE_HPP

max_stars_repo_name: truongnmt/iroha

max_issues_repo_name: truongnmt/iroha

max_forks_repo_name: truongnmt/iroha


text:
#pragma once

#include <chrono>
#include <list>
#include <optional>
#include <sstream>
#include <variant>

#include <boost/asio/buffer.hpp>

#include "core/core.hpp"
#include "core/id.hpp"
#include "core/web/web_types.hpp"

class ApplicationVersion;
class TournamentStore;
class Action;

class NetworkMessage {
public:
    enum class Type {
        HANDSHAKE, // The message contains the initial connection handshake
        SYNC, // The message contains the entire serialized tournament
        SYNC_ACK, // The message acknowledges the sync
        ACTION, // The message contains a serialized action
        ACTION_ACK, // The message acknowledges an action
        UNDO, // The message undoes a previously sent action
        UNDO_ACK, // The message acknowledges an undo
        QUIT, // The participant or server has quit. Not used for web connection
        CLOCK_SYNC, // Message used for sending current master time
        CLOCK_SYNC_REQUEST, // Message used for requesting current time of master

        // Messages used for communication with the web server
        REQUEST_WEB_TOKEN,
        REQUEST_WEB_TOKEN_RESPONSE,
        VALIDATE_WEB_TOKEN,
        VALIDATE_WEB_TOKEN_RESPONSE,
        REGISTER_WEB_NAME,
        REGISTER_WEB_NAME_RESPONSE,
        CHECK_WEB_NAME,
        CHECK_WEB_NAME_RESPONSE,
    };

    NetworkMessage();

    boost::asio::mutable_buffer headerBuffer();
    boost::asio::mutable_buffer bodyBuffer();

    bool decodeHeader();
    size_t bodySize() const;
    Type getType() const;

    void encodeHandshake();
    bool decodeHandshake(ApplicationVersion &version);

    typedef std::list<std::pair<ClientActionId, std::shared_ptr<Action>>> SharedActionList;
    void encodeSync(const TournamentStore & tournament, const SharedActionList &actionStack);
    bool decodeSync(TournamentStore & tournament, SharedActionList &actionStack);

    void encodeSyncAck();

    void encodeAction(const ClientActionId &actionId, const std::shared_ptr<Action> &action);
    bool decodeAction(ClientActionId &actionId, std::shared_ptr<Action> &action);

    void encodeActionAck(const ClientActionId &actionId);
    bool decodeActionAck(ClientActionId &actionId);

    void encodeQuit();

    void encodeUndo(const ClientActionId &actionId);
    bool decodeUndo(ClientActionId &actionId);

    void encodeUndoAck(const ClientActionId &actionId);
    bool decodeUndoAck(ClientActionId &actionId);

    void encodeRequestWebToken(const std::string &email, const std::string &password);
    bool decodeRequestWebToken(std::string &email, std::string &password);

    void encodeRequestWebTokenResponse(WebTokenRequestResponse response, const std::optional<WebToken> &token);
    bool decodeRequestWebTokenResponse(WebTokenRequestResponse &response, std::optional<WebToken> &token);

    void encodeValidateWebToken(const std::string &email, const WebToken &token);
    bool decodeValidateWebToken(std::string &email, WebToken &token);

    void encodeValidateWebTokenResponse(WebTokenValidationResponse response);
    bool decodeValidateWebTokenResponse(WebTokenValidationResponse &response);

    void encodeRegisterWebName(const TournamentId &id, const std::string &webName);
    bool decodeRegisterWebName(TournamentId &id, std::string &webName);

    void encodeRegisterWebNameResponse(const WebNameRegistrationResponse &response);
    bool decodeRegisterWebNameResponse(WebNameRegistrationResponse &response);

    void encodeCheckWebName(const TournamentId &id, const std::string &webName);
    bool decodeCheckWebName(TournamentId &id, std::string &webName);

    void encodeCheckWebNameResponse(const WebNameCheckResponse &response);
    bool decodeCheckWebNameResponse(WebNameCheckResponse  &response);

    void encodeClockSyncRequest();

    void encodeClockSync(const std::chrono::milliseconds &time);
    bool decodeClockSync(std::chrono::milliseconds &time);

private:
    void encodeHeader();

    Type mType;
    size_t mUncompressedSize;
    std::string mHeader;
    std::string mBody;
};

std::ostream &operator<<(std::ostream &o, NetworkMessage::Type type);

max_stars_repo_name: svendcsvendsen/judoassistant

max_issues_repo_name: svendcsvendsen/judoassistant

max_forks_repo_name: judoassistant/judoassistant