<commit_before>// Copyright 2021 Google LLC
//
// 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 "google/cloud/storage/client.h"
#include "google/cloud/storage/testing/storage_integration_test.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/testing_util/scoped_environment.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <gmock/gmock.h>

namespace google {
namespace cloud {
namespace storage {
inline namespace STORAGE_CLIENT_NS {
namespace {

using ::google::cloud::internal::GetEnv;
using ::google::cloud::testing_util::IsOk;

class ObjectReadRangeIntegrationTest
    : public ::google::cloud::storage::testing::StorageIntegrationTest {
 public:
  ObjectReadRangeIntegrationTest() = default;

 protected:
  void SetUp() override {
    bucket_name_ =
        GetEnv("GOOGLE_CLOUD_CPP_STORAGE_TEST_BUCKET_NAME").value_or("");

    ASSERT_FALSE(bucket_name_.empty());
  }

  std::string const& bucket_name() const { return bucket_name_; }

 private:
  std::string bucket_name_;
};

TEST_F(ObjectReadRangeIntegrationTest, ReadRangeSmall) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t begin;
    std::int64_t end;
    std::string expected;
  } cases[] = {
      {0, 1, contents.substr(0, 1)},
      {4, 8, contents.substr(4, 4)},
      {0, size, contents},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [" + std::to_string(test.begin) + "," +
                 std::to_string(test.end) + ")");
    auto reader = client->ReadObject(bucket_name(), object_name,
                                     ReadRange(test.begin, test.end));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

TEST_F(ObjectReadRangeIntegrationTest, ReadFromOffset) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t offset;
    std::string expected;
  } cases[] = {
      {0, contents.substr(0)},
      {4, contents.substr(4)},
      {size - 1, contents.substr(size - 1)},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [" + std::to_string(test.offset) + ",end)");
    auto reader = client->ReadObject(bucket_name(), object_name,
                                     ReadFromOffset(test.offset));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

TEST_F(ObjectReadRangeIntegrationTest, ReadLast) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t offset;
    std::string expected;
  } cases[] = {
      {1, contents.substr(size - 1)},
      {4, contents.substr(size - 4)},
      {size, contents},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [-" + std::to_string(test.offset) + ",end)");
    auto reader =
        client->ReadObject(bucket_name(), object_name, ReadLast(test.offset));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

}  // namespace
}  // namespace STORAGE_CLIENT_NS
}  // namespace storage
}  // namespace cloud
}  // namespace google
<commit_msg>test(storage): fix build for Windows+x86 (#6555)<commit_after>// Copyright 2021 Google LLC
//
// 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 "google/cloud/storage/client.h"
#include "google/cloud/storage/testing/storage_integration_test.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/testing_util/scoped_environment.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <gmock/gmock.h>

namespace google {
namespace cloud {
namespace storage {
inline namespace STORAGE_CLIENT_NS {
namespace {

using ::google::cloud::internal::GetEnv;
using ::google::cloud::testing_util::IsOk;

class ObjectReadRangeIntegrationTest
    : public ::google::cloud::storage::testing::StorageIntegrationTest {
 public:
  ObjectReadRangeIntegrationTest() = default;

 protected:
  void SetUp() override {
    bucket_name_ =
        GetEnv("GOOGLE_CLOUD_CPP_STORAGE_TEST_BUCKET_NAME").value_or("");

    ASSERT_FALSE(bucket_name_.empty());
  }

  std::string const& bucket_name() const { return bucket_name_; }

 private:
  std::string bucket_name_;
};

TEST_F(ObjectReadRangeIntegrationTest, ReadRangeSmall) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto const size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t begin;
    std::int64_t end;
    std::string expected;
  } cases[] = {
      {0, 1, contents.substr(0, 1)},
      {4, 8, contents.substr(4, 4)},
      {0, size, contents},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [" + std::to_string(test.begin) + "," +
                 std::to_string(test.end) + ")");
    auto reader = client->ReadObject(bucket_name(), object_name,
                                     ReadRange(test.begin, test.end));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

TEST_F(ObjectReadRangeIntegrationTest, ReadFromOffset) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto const size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t offset;
    std::string expected;
  } cases[] = {
      {0, contents.substr(0)},
      {4, contents.substr(4)},
      {size - 1, contents.substr(contents.size() - 1)},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [" + std::to_string(test.offset) + ",end)");
    auto reader = client->ReadObject(bucket_name(), object_name,
                                     ReadFromOffset(test.offset));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

TEST_F(ObjectReadRangeIntegrationTest, ReadLast) {
  StatusOr<Client> client = MakeIntegrationTestClient();
  ASSERT_STATUS_OK(client);

  auto const contents = LoremIpsum();
  auto const object_name = MakeRandomObjectName();

  auto insert = client->InsertObject(bucket_name(), object_name, contents,
                                     IfGenerationMatch(0));
  ASSERT_THAT(insert, IsOk());
  EXPECT_THAT(contents.size(), insert->size());

  auto const size = static_cast<std::int64_t>(insert->size());

  // Read several small portions of the object, expecting specific results.
  struct Test {
    std::int64_t offset;
    std::string expected;
  } cases[] = {
      {1, contents.substr(contents.size() - 1)},
      {4, contents.substr(contents.size() - 4)},
      {size, contents},
  };

  for (auto const& test : cases) {
    SCOPED_TRACE("Testing range [-" + std::to_string(test.offset) + ",end)");
    auto reader =
        client->ReadObject(bucket_name(), object_name, ReadLast(test.offset));
    auto actual = std::string{std::istreambuf_iterator<char>(reader), {}};
    EXPECT_THAT(reader.status(), IsOk());
    EXPECT_EQ(test.expected, actual);
  }

  (void)client->DeleteObject(bucket_name(), object_name);
}

}  // namespace
}  // namespace STORAGE_CLIENT_NS
}  // namespace storage
}  // namespace cloud
}  // namespace google
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2015 Dato, Inc.
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the BSD license. See the LICENSE file for details.
 */
#include <cassert>
#include <sstream>
#include <zmq.h>
#include <boost/algorithm/string.hpp>
#include <boost/integer_traits.hpp>
#include <util/md5.hpp>
#include <globals/globals.hpp>
#include <logger/logger.hpp>
#include <export.hpp>

#ifndef _WIN32
#include <sys/socket.h>
#include <sys/un.h>
#endif

namespace libfault {
int SEND_TIMEOUT = 3000;
int RECV_TIMEOUT = 7000;

void set_send_timeout(int ms) {
  SEND_TIMEOUT = ms;
}
void set_recv_timeout(int ms) {
  RECV_TIMEOUT = ms;
}

void set_conservative_socket_parameters(void* z_socket) {
  int lingerval = 500;
  int timeoutms = 500;
  int hwm = 0;
  int rc = zmq_setsockopt(z_socket, ZMQ_LINGER, &lingerval, sizeof(lingerval));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_RCVTIMEO, &timeoutms, sizeof(timeoutms));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_SNDTIMEO, &timeoutms, sizeof(timeoutms));
  assert(rc == 0);

  rc = zmq_setsockopt(z_socket, ZMQ_SNDHWM, &hwm, sizeof(hwm));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_RCVHWM, &hwm, sizeof(hwm));
  assert(rc == 0);

}

/**
 * Given a string, returns a zeromq localhost tcp address (ex:
 * tcp://127.15.21.22:11111).
 *
 * On windows we don't get zeromq IPC sockets. Hence, the easiest thing to do
 * is to remap ipc sockets to tcp addresses.
 *
 * When the server is started with address=default mode, on *nix systems we
 * map to ipc://something or order. Instead, on windows systems
 * we must map to tcp://[arbitrary local IP] where there is optimally,
 * a 1-1 correspondence between the local IP and the PID.
 *
 * So, here are the rules:
 * - We cannot generate any port number <= 1024
 * - Lets about 127.0.0.1 because too many stuff like to live there
 * - 127.0.0.0 is invalid. (network address)
 * - 127.255.255.255 is invalid (broadcast address)
 */
std::string hash_string_to_tcp_address(const std::string& s) {
  std::string md5sum = graphlab::md5_raw(s);
  // we get approximately 5 bytes of entropy (yes really somewhat less)

  unsigned char addr[4];
  addr[0] = 127;
  addr[1] = md5sum[0];
  addr[2] = md5sum[1];
  addr[3] = md5sum[2];
  uint16_t port = (uint16_t)(md5sum[3]) * 256 + md5sum[4];

  // validate
  if ((addr[1] == 0 && addr[2] == 0 && addr[3] == 0) ||  // network address
      (addr[1] == 0 && addr[2] == 0 && addr[3] == 1) ||  // common address
      (addr[1] == 255 && addr[2] == 255 && addr[3] == 255) ||  // broadcast
      (port <= 1024)) { // bad port
    // bad. this is network name
    // rehash
    return hash_string_to_tcp_address(md5sum);
  }

  // ok generate the string
  std::stringstream strm;
  strm << "tcp://" << (int)(addr[0]) << "."
                   << (int)(addr[1]) << "."
                   << (int)(addr[2]) << "."
                   << (int)(addr[3]) << ":"
                   << (int)(port);

  std::string s_out = strm.str();

  logstream(LOG_INFO) << "normalize_address: Hashed ipc address '" << s << "' to '"
                      << s_out << "'." << std::endl;
  return s_out;
}

EXPORT int64_t FORCE_IPC_TO_TCP_FALLBACK = 0;

REGISTER_GLOBAL(int64_t, FORCE_IPC_TO_TCP_FALLBACK, true);

std::string normalize_address(const std::string& address) {

  bool use_tcp_fallback = (FORCE_IPC_TO_TCP_FALLBACK != 0);

  std::string address_out;

#ifdef _WIN32
  use_tcp_fallback = true;
#endif

  if(use_tcp_fallback) {

    logstream(LOG_INFO) << "normalize_address: Using TCP fallback mode." << std::endl;

    if (boost::starts_with(address, "ipc://")) {
      address_out = hash_string_to_tcp_address(address);
    } else {
      address_out = address;
    }
  } else {
    /*
     *
     ipc sockets on Linux and Mac use Unix domain sockets which have a maximum
     length defined by

     #include <iostream>
     #include <sys/socket.h>
     #include <sys/un.h>

     int main() {
     struct sockaddr_un my_addr;
     std::cout << sizeof(my_addr.sun_path) << std::endl;
     }
     This appears to be 104 on Mac OS X 10.11 and 108 on a Ubuntu machine
     (length includes the null terminator).

     See http://man7.org/linux/man-pages/man7/unix.7.html
    */
    struct sockaddr_un un_addr;
    size_t max_length = sizeof(un_addr.sun_path) - 1;  // null terminator
    if (boost::starts_with(address, "ipc://") &&
        address.length() > max_length) { // strictly this leaves a 5 char buffer
      // since we didn't strip the ipc://
      // we hash it to a file we put in /tmp
      // we could use $TMPDIR but that might be a bad idea.
      // since $TMPDIR could bump the length much bigger again.
      // with /tmp the length is bounded to strlen("/tmp") + md5 length.
      std::string md5_hash = graphlab::md5(address);
      address_out = "ipc:///tmp/" + md5_hash;
    } else {
      address_out = address;
    }
  }

  if(address_out == address) {
    logstream(LOG_INFO) << "normalize_address: kept '" << address_out << "'." << std::endl;
  } else {
    logstream(LOG_INFO) << "normalize_address: '" << address << "' --> '"
                        << address_out << "'." << std::endl;
  }

  return address_out;
}

};
<commit_msg>sockaddr_un not defined on windows<commit_after>/**
 * Copyright (C) 2015 Dato, Inc.
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the BSD license. See the LICENSE file for details.
 */
#include <cassert>
#include <sstream>
#include <zmq.h>
#include <boost/algorithm/string.hpp>
#include <boost/integer_traits.hpp>
#include <util/md5.hpp>
#include <globals/globals.hpp>
#include <logger/logger.hpp>
#include <export.hpp>

#ifndef _WIN32
#include <sys/socket.h>
#include <sys/un.h>
#endif

namespace libfault {
int SEND_TIMEOUT = 3000;
int RECV_TIMEOUT = 7000;

void set_send_timeout(int ms) {
  SEND_TIMEOUT = ms;
}
void set_recv_timeout(int ms) {
  RECV_TIMEOUT = ms;
}

void set_conservative_socket_parameters(void* z_socket) {
  int lingerval = 500;
  int timeoutms = 500;
  int hwm = 0;
  int rc = zmq_setsockopt(z_socket, ZMQ_LINGER, &lingerval, sizeof(lingerval));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_RCVTIMEO, &timeoutms, sizeof(timeoutms));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_SNDTIMEO, &timeoutms, sizeof(timeoutms));
  assert(rc == 0);

  rc = zmq_setsockopt(z_socket, ZMQ_SNDHWM, &hwm, sizeof(hwm));
  assert(rc == 0);
  rc = zmq_setsockopt(z_socket, ZMQ_RCVHWM, &hwm, sizeof(hwm));
  assert(rc == 0);

}

/**
 * Given a string, returns a zeromq localhost tcp address (ex:
 * tcp://127.15.21.22:11111).
 *
 * On windows we don't get zeromq IPC sockets. Hence, the easiest thing to do
 * is to remap ipc sockets to tcp addresses.
 *
 * When the server is started with address=default mode, on *nix systems we
 * map to ipc://something or order. Instead, on windows systems
 * we must map to tcp://[arbitrary local IP] where there is optimally,
 * a 1-1 correspondence between the local IP and the PID.
 *
 * So, here are the rules:
 * - We cannot generate any port number <= 1024
 * - Lets about 127.0.0.1 because too many stuff like to live there
 * - 127.0.0.0 is invalid. (network address)
 * - 127.255.255.255 is invalid (broadcast address)
 */
std::string hash_string_to_tcp_address(const std::string& s) {
  std::string md5sum = graphlab::md5_raw(s);
  // we get approximately 5 bytes of entropy (yes really somewhat less)

  unsigned char addr[4];
  addr[0] = 127;
  addr[1] = md5sum[0];
  addr[2] = md5sum[1];
  addr[3] = md5sum[2];
  uint16_t port = (uint16_t)(md5sum[3]) * 256 + md5sum[4];

  // validate
  if ((addr[1] == 0 && addr[2] == 0 && addr[3] == 0) ||  // network address
      (addr[1] == 0 && addr[2] == 0 && addr[3] == 1) ||  // common address
      (addr[1] == 255 && addr[2] == 255 && addr[3] == 255) ||  // broadcast
      (port <= 1024)) { // bad port
    // bad. this is network name
    // rehash
    return hash_string_to_tcp_address(md5sum);
  }

  // ok generate the string
  std::stringstream strm;
  strm << "tcp://" << (int)(addr[0]) << "."
                   << (int)(addr[1]) << "."
                   << (int)(addr[2]) << "."
                   << (int)(addr[3]) << ":"
                   << (int)(port);

  std::string s_out = strm.str();

  logstream(LOG_INFO) << "normalize_address: Hashed ipc address '" << s << "' to '"
                      << s_out << "'." << std::endl;
  return s_out;
}

EXPORT int64_t FORCE_IPC_TO_TCP_FALLBACK = 0;

REGISTER_GLOBAL(int64_t, FORCE_IPC_TO_TCP_FALLBACK, true);

std::string normalize_address(const std::string& address) {

  bool use_tcp_fallback = (FORCE_IPC_TO_TCP_FALLBACK != 0);

  std::string address_out;

#ifdef _WIN32
  use_tcp_fallback = true;
#endif

  if(use_tcp_fallback) {

    logstream(LOG_INFO) << "normalize_address: Using TCP fallback mode." << std::endl;

    if (boost::starts_with(address, "ipc://")) {
      address_out = hash_string_to_tcp_address(address);
    } else {
      address_out = address;
    }
  }
#ifndef _WIN32
  // sockaddr_un not defined on windows.
  else {
    /*
     *
     ipc sockets on Linux and Mac use Unix domain sockets which have a maximum
     length defined by

     #include <iostream>
     #include <sys/socket.h>
     #include <sys/un.h>

     int main() {
     struct sockaddr_un my_addr;
     std::cout << sizeof(my_addr.sun_path) << std::endl;
     }
     This appears to be 104 on Mac OS X 10.11 and 108 on a Ubuntu machine
     (length includes the null terminator).

     See http://man7.org/linux/man-pages/man7/unix.7.html
    */
    struct sockaddr_un un_addr;
    size_t max_length = sizeof(un_addr.sun_path) - 1;  // null terminator
    if (boost::starts_with(address, "ipc://") &&
        address.length() > max_length) { // strictly this leaves a 5 char buffer
      // since we didn't strip the ipc://
      // we hash it to a file we put in /tmp
      // we could use $TMPDIR but that might be a bad idea.
      // since $TMPDIR could bump the length much bigger again.
      // with /tmp the length is bounded to strlen("/tmp") + md5 length.
      std::string md5_hash = graphlab::md5(address);
      address_out = "ipc:///tmp/" + md5_hash;
    } else {
      address_out = address;
    }
  }
#else
  else {
    address_out = address;
  }
#endif

  if(address_out == address) {
    logstream(LOG_INFO) << "normalize_address: kept '" << address_out << "'." << std::endl;
  } else {
    logstream(LOG_INFO) << "normalize_address: '" << address << "' --> '"
                        << address_out << "'." << std::endl;
  }

  return address_out;
}

};
<|endoftext|>


<commit_before>#include "Genes/Passed_Pawn_Gene.h"

#include <string>
#include <array>

#include "Genes/Gene.h"

#include "Game/Board.h"
#include "Game/Piece.h"
#include "Game/Color.h"

double Passed_Pawn_Gene::score_board(const Board& board, Piece_Color perspective, size_t) const noexcept
{
    double score = 0.0;
    auto own_pawn = Piece{perspective, Piece_Type::PAWN};
    auto other_pawn = Piece{opposite(perspective), Piece_Type::PAWN};
    auto near_rank = (perspective == Piece_Color::WHITE ? 1 : 8);
    auto far_rank  = (perspective == Piece_Color::WHITE ? 7 : 2);
    auto rank_step = (perspective == Piece_Color::WHITE ? 1 : -1);
    auto other_pawn_ranks_occupied = std::array<int, 8>{};

    for(char file = 'a'; file <= 'h'; ++file)
    {
        for(int rank = far_rank; rank != near_rank; rank -= rank_step)
        {
            auto piece = board.piece_on_square({file, rank});
            if(piece == own_pawn)
            {
                score += 1.0;
                auto left_file  = std::max('a', char(file - 1));
                auto right_file = std::min('h', char(file + 1));
                auto score_diff = 1.0/(right_file - left_file + 1);

                for(char pawn_file = left_file; pawn_file <= right_file; ++pawn_file)
                {
                    auto other_pawn_rank = other_pawn_ranks_occupied[size_t(pawn_file - 'a')];
                    if(other_pawn_rank != 0 && other_pawn_rank != rank)
                    {
                        score -= score_diff;
                    }
                }
            }
            else if(piece == other_pawn)
            {
                other_pawn_ranks_occupied[size_t(file - 'a')] = rank;
            }
        }
    }

    return score/8; // maximum score == 1
}

std::string Passed_Pawn_Gene::name() const noexcept
{
    return "Passed Pawn Gene";
}
<commit_msg>Slight speed increase for Passed Pawn Gene<commit_after>#include "Genes/Passed_Pawn_Gene.h"

#include <string>
#include <array>

#include "Genes/Gene.h"

#include "Game/Board.h"
#include "Game/Piece.h"
#include "Game/Color.h"

double Passed_Pawn_Gene::score_board(const Board& board, Piece_Color perspective, size_t) const noexcept
{
    double score = 0.0;
    auto own_pawn = Piece{perspective, Piece_Type::PAWN};
    auto other_pawn = Piece{opposite(perspective), Piece_Type::PAWN};
    auto near_rank = (perspective == Piece_Color::WHITE ? 1 : 8);
    auto far_rank  = (perspective == Piece_Color::WHITE ? 7 : 2);
    auto rank_step = (perspective == Piece_Color::WHITE ? 1 : -1);
    auto other_pawn_ranks_occupied = std::array<int, 8>{};

    for(char file = 'a'; file <= 'h'; ++file)
    {
        auto left_file  = std::max('a', char(file - 1));
        auto right_file = std::min('h', char(file + 1));
        auto score_diff = 1.0/(right_file - left_file + 1);

        for(int rank = far_rank; rank != near_rank; rank -= rank_step)
        {
            auto piece = board.piece_on_square({file, rank});
            if(piece == own_pawn)
            {
                score += 1.0;

                for(char pawn_file = left_file; pawn_file <= right_file; ++pawn_file)
                {
                    auto other_pawn_rank = other_pawn_ranks_occupied[size_t(pawn_file - 'a')];
                    if(other_pawn_rank != 0 && other_pawn_rank != rank)
                    {
                        score -= score_diff;
                    }
                }
            }
            else if(piece == other_pawn)
            {
                other_pawn_ranks_occupied[size_t(file - 'a')] = rank;
            }
        }
    }

    return score/8; // maximum score == 1
}

std::string Passed_Pawn_Gene::name() const noexcept
{
    return "Passed Pawn Gene";
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/heap/safepoint.h"

#include "vm/heap/heap.h"
#include "vm/thread.h"
#include "vm/thread_registry.h"

namespace dart {

DEFINE_FLAG(bool, trace_safepoint, false, "Trace Safepoint logic.");

SafepointOperationScope::SafepointOperationScope(Thread* T)
    : ThreadStackResource(T) {
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  SafepointHandler* handler = I->group()->safepoint_handler();
  ASSERT(handler != NULL);

  // Signal all threads to get to a safepoint and wait for them to
  // get to a safepoint.
  handler->SafepointThreads(T);
}

SafepointOperationScope::~SafepointOperationScope() {
  Thread* T = thread();
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  // Resume all threads which are blocked for the safepoint operation.
  SafepointHandler* handler = I->safepoint_handler();
  ASSERT(handler != NULL);
  handler->ResumeThreads(T);
}

ForceGrowthSafepointOperationScope::ForceGrowthSafepointOperationScope(
    Thread* T)
    : ThreadStackResource(T) {
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  Heap* heap = I->heap();
  current_growth_controller_state_ = heap->GrowthControlState();
  heap->DisableGrowthControl();

  SafepointHandler* handler = I->group()->safepoint_handler();
  ASSERT(handler != NULL);

  // Signal all threads to get to a safepoint and wait for them to
  // get to a safepoint.
  handler->SafepointThreads(T);
}

ForceGrowthSafepointOperationScope::~ForceGrowthSafepointOperationScope() {
  Thread* T = thread();
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  // Resume all threads which are blocked for the safepoint operation.
  SafepointHandler* handler = I->safepoint_handler();
  ASSERT(handler != NULL);
  handler->ResumeThreads(T);

  Heap* heap = I->heap();
  heap->SetGrowthControlState(current_growth_controller_state_);

  if (current_growth_controller_state_) {
    ASSERT(T->CanCollectGarbage());
    // Check if we passed the growth limit during the scope.
    if (heap->old_space()->NeedsGarbageCollection()) {
      heap->CollectGarbage(Heap::kMarkSweep, Heap::kOldSpace);
    } else {
      heap->CheckStartConcurrentMarking(T, Heap::kOldSpace);
    }
  }
}

SafepointHandler::SafepointHandler(IsolateGroup* isolate_group)
    : isolate_group_(isolate_group),
      safepoint_lock_(),
      number_threads_not_at_safepoint_(0),
      safepoint_operation_count_(0),
      owner_(NULL) {}

SafepointHandler::~SafepointHandler() {
  ASSERT(owner_ == NULL);
  ASSERT(safepoint_operation_count_ == 0);
  isolate_group_ = NULL;
}

void SafepointHandler::SafepointThreads(Thread* T) {
  ASSERT(T->no_safepoint_scope_depth() == 0);
  ASSERT(T->execution_state() == Thread::kThreadInVM);

  {
    // First grab the threads list lock for this isolate
    // and check if a safepoint is already in progress. This
    // ensures that two threads do not start a safepoint operation
    // at the same time.
    MonitorLocker sl(threads_lock());

    // Now check to see if a safepoint operation is already in progress
    // for this isolate, block if an operation is in progress.
    while (SafepointInProgress()) {
      // If we are recursively invoking a Safepoint operation then we
      // just increment the count and return, otherwise we wait for the
      // safepoint operation to be done.
      if (owner_ == T) {
        increment_safepoint_operation_count();
        return;
      }
      sl.WaitWithSafepointCheck(T);
    }

    // Set safepoint in progress state by this thread.
    SetSafepointInProgress(T);

    // Go over the active thread list and ensure that all threads active
    // in the isolate reach a safepoint.
    Thread* current = isolate_group()->thread_registry()->active_list();
    while (current != NULL) {
      MonitorLocker tl(current->thread_lock());
      if (!current->BypassSafepoints()) {
        if (current == T) {
          current->SetAtSafepoint(true);
        } else {
          uint32_t state = current->SetSafepointRequested(true);
          if (!Thread::IsAtSafepoint(state)) {
            // Thread is not already at a safepoint so try to
            // get it to a safepoint and wait for it to check in.
            if (current->IsMutatorThread()) {
              ASSERT(T->isolate() != NULL);
              current->ScheduleInterruptsLocked(Thread::kVMInterrupt);
            }
            MonitorLocker sl(&safepoint_lock_);
            ++number_threads_not_at_safepoint_;
          }
        }
      }
      current = current->next();
    }
  }
  // Now wait for all threads that are not already at a safepoint to check-in.
  {
    MonitorLocker sl(&safepoint_lock_);
    intptr_t num_attempts = 0;
    while (number_threads_not_at_safepoint_ > 0) {
      Monitor::WaitResult retval = sl.Wait(1000);
      if (retval == Monitor::kTimedOut) {
        num_attempts += 1;
        if (FLAG_trace_safepoint && num_attempts > 10) {
          // We have been waiting too long, start logging this as we might
          // have an issue where a thread is not checking in for a safepoint.
          for (Thread* current =
                   isolate_group()->thread_registry()->active_list();
               current != NULL; current = current->next()) {
            if (!current->IsAtSafepoint()) {
              OS::PrintErr("Attempt:%" Pd
                           " waiting for thread %s to check in\n",
                           num_attempts, current->os_thread()->name());
            }
          }
        }
      }
    }
  }
}

void SafepointHandler::ResumeThreads(Thread* T) {
  // First resume all the threads which are blocked for the safepoint
  // operation.
  MonitorLocker sl(threads_lock());

  // First check if we are in a recursive safepoint operation, in that case
  // we just decrement safepoint_operation_count and return.
  ASSERT(SafepointInProgress());
  if (safepoint_operation_count() > 1) {
    decrement_safepoint_operation_count();
    return;
  }
  Thread* current = isolate_group()->thread_registry()->active_list();
  while (current != NULL) {
    MonitorLocker tl(current->thread_lock());
    if (!current->BypassSafepoints()) {
      if (current == T) {
        current->SetAtSafepoint(false);
      } else {
        uint32_t state = current->SetSafepointRequested(false);
        if (Thread::IsBlockedForSafepoint(state)) {
          tl.Notify();
        }
      }
    }
    current = current->next();
  }
  // Now reset the safepoint_in_progress_ state and notify all threads
  // that are waiting to enter the isolate or waiting to start another
  // safepoint operation.
  ResetSafepointInProgress(T);
  sl.NotifyAll();
}

void SafepointHandler::EnterSafepointUsingLock(Thread* T) {
  MonitorLocker tl(T->thread_lock());
  T->SetAtSafepoint(true);
  if (T->IsSafepointRequested()) {
    MonitorLocker sl(&safepoint_lock_);
    ASSERT(number_threads_not_at_safepoint_ > 0);
    number_threads_not_at_safepoint_ -= 1;
    sl.Notify();
  }
}

void SafepointHandler::ExitSafepointUsingLock(Thread* T) {
  MonitorLocker tl(T->thread_lock());
  ASSERT(T->IsAtSafepoint());
  while (T->IsSafepointRequested()) {
    T->SetBlockedForSafepoint(true);
    tl.Wait();
    T->SetBlockedForSafepoint(false);
  }
  T->SetAtSafepoint(false);
}

void SafepointHandler::BlockForSafepoint(Thread* T) {
  ASSERT(!T->BypassSafepoints());
  MonitorLocker tl(T->thread_lock());
  if (T->IsSafepointRequested()) {
    T->SetAtSafepoint(true);
    {
      MonitorLocker sl(&safepoint_lock_);
      ASSERT(number_threads_not_at_safepoint_ > 0);
      number_threads_not_at_safepoint_ -= 1;
      sl.Notify();
    }
    while (T->IsSafepointRequested()) {
      T->SetBlockedForSafepoint(true);
      tl.Wait();
      T->SetBlockedForSafepoint(false);
    }
    T->SetAtSafepoint(false);
  }
}

}  // namespace dart
<commit_msg>[vm, gc] Fix racy access to the growth policy in ForceGrowthSafepointOperationScope.<commit_after>// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/heap/safepoint.h"

#include "vm/heap/heap.h"
#include "vm/thread.h"
#include "vm/thread_registry.h"

namespace dart {

DEFINE_FLAG(bool, trace_safepoint, false, "Trace Safepoint logic.");

SafepointOperationScope::SafepointOperationScope(Thread* T)
    : ThreadStackResource(T) {
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  SafepointHandler* handler = I->group()->safepoint_handler();
  ASSERT(handler != NULL);

  // Signal all threads to get to a safepoint and wait for them to
  // get to a safepoint.
  handler->SafepointThreads(T);
}

SafepointOperationScope::~SafepointOperationScope() {
  Thread* T = thread();
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  // Resume all threads which are blocked for the safepoint operation.
  SafepointHandler* handler = I->safepoint_handler();
  ASSERT(handler != NULL);
  handler->ResumeThreads(T);
}

ForceGrowthSafepointOperationScope::ForceGrowthSafepointOperationScope(
    Thread* T)
    : ThreadStackResource(T) {
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  SafepointHandler* handler = I->group()->safepoint_handler();
  ASSERT(handler != NULL);

  // Signal all threads to get to a safepoint and wait for them to
  // get to a safepoint.
  handler->SafepointThreads(T);

  // N.B.: Change growth policy inside the safepoint to prevent racy access.
  Heap* heap = I->heap();
  current_growth_controller_state_ = heap->GrowthControlState();
  heap->DisableGrowthControl();
}

ForceGrowthSafepointOperationScope::~ForceGrowthSafepointOperationScope() {
  Thread* T = thread();
  ASSERT(T != NULL);
  Isolate* I = T->isolate();
  ASSERT(I != NULL);

  // N.B.: Change growth policy inside the safepoint to prevent racy access.
  Heap* heap = I->heap();
  heap->SetGrowthControlState(current_growth_controller_state_);

  // Resume all threads which are blocked for the safepoint operation.
  SafepointHandler* handler = I->safepoint_handler();
  ASSERT(handler != NULL);
  handler->ResumeThreads(T);

  if (current_growth_controller_state_) {
    ASSERT(T->CanCollectGarbage());
    // Check if we passed the growth limit during the scope.
    if (heap->old_space()->NeedsGarbageCollection()) {
      heap->CollectGarbage(Heap::kMarkSweep, Heap::kOldSpace);
    } else {
      heap->CheckStartConcurrentMarking(T, Heap::kOldSpace);
    }
  }
}

SafepointHandler::SafepointHandler(IsolateGroup* isolate_group)
    : isolate_group_(isolate_group),
      safepoint_lock_(),
      number_threads_not_at_safepoint_(0),
      safepoint_operation_count_(0),
      owner_(NULL) {}

SafepointHandler::~SafepointHandler() {
  ASSERT(owner_ == NULL);
  ASSERT(safepoint_operation_count_ == 0);
  isolate_group_ = NULL;
}

void SafepointHandler::SafepointThreads(Thread* T) {
  ASSERT(T->no_safepoint_scope_depth() == 0);
  ASSERT(T->execution_state() == Thread::kThreadInVM);

  {
    // First grab the threads list lock for this isolate
    // and check if a safepoint is already in progress. This
    // ensures that two threads do not start a safepoint operation
    // at the same time.
    MonitorLocker sl(threads_lock());

    // Now check to see if a safepoint operation is already in progress
    // for this isolate, block if an operation is in progress.
    while (SafepointInProgress()) {
      // If we are recursively invoking a Safepoint operation then we
      // just increment the count and return, otherwise we wait for the
      // safepoint operation to be done.
      if (owner_ == T) {
        increment_safepoint_operation_count();
        return;
      }
      sl.WaitWithSafepointCheck(T);
    }

    // Set safepoint in progress state by this thread.
    SetSafepointInProgress(T);

    // Go over the active thread list and ensure that all threads active
    // in the isolate reach a safepoint.
    Thread* current = isolate_group()->thread_registry()->active_list();
    while (current != NULL) {
      MonitorLocker tl(current->thread_lock());
      if (!current->BypassSafepoints()) {
        if (current == T) {
          current->SetAtSafepoint(true);
        } else {
          uint32_t state = current->SetSafepointRequested(true);
          if (!Thread::IsAtSafepoint(state)) {
            // Thread is not already at a safepoint so try to
            // get it to a safepoint and wait for it to check in.
            if (current->IsMutatorThread()) {
              ASSERT(T->isolate() != NULL);
              current->ScheduleInterruptsLocked(Thread::kVMInterrupt);
            }
            MonitorLocker sl(&safepoint_lock_);
            ++number_threads_not_at_safepoint_;
          }
        }
      }
      current = current->next();
    }
  }
  // Now wait for all threads that are not already at a safepoint to check-in.
  {
    MonitorLocker sl(&safepoint_lock_);
    intptr_t num_attempts = 0;
    while (number_threads_not_at_safepoint_ > 0) {
      Monitor::WaitResult retval = sl.Wait(1000);
      if (retval == Monitor::kTimedOut) {
        num_attempts += 1;
        if (FLAG_trace_safepoint && num_attempts > 10) {
          // We have been waiting too long, start logging this as we might
          // have an issue where a thread is not checking in for a safepoint.
          for (Thread* current =
                   isolate_group()->thread_registry()->active_list();
               current != NULL; current = current->next()) {
            if (!current->IsAtSafepoint()) {
              OS::PrintErr("Attempt:%" Pd
                           " waiting for thread %s to check in\n",
                           num_attempts, current->os_thread()->name());
            }
          }
        }
      }
    }
  }
}

void SafepointHandler::ResumeThreads(Thread* T) {
  // First resume all the threads which are blocked for the safepoint
  // operation.
  MonitorLocker sl(threads_lock());

  // First check if we are in a recursive safepoint operation, in that case
  // we just decrement safepoint_operation_count and return.
  ASSERT(SafepointInProgress());
  if (safepoint_operation_count() > 1) {
    decrement_safepoint_operation_count();
    return;
  }
  Thread* current = isolate_group()->thread_registry()->active_list();
  while (current != NULL) {
    MonitorLocker tl(current->thread_lock());
    if (!current->BypassSafepoints()) {
      if (current == T) {
        current->SetAtSafepoint(false);
      } else {
        uint32_t state = current->SetSafepointRequested(false);
        if (Thread::IsBlockedForSafepoint(state)) {
          tl.Notify();
        }
      }
    }
    current = current->next();
  }
  // Now reset the safepoint_in_progress_ state and notify all threads
  // that are waiting to enter the isolate or waiting to start another
  // safepoint operation.
  ResetSafepointInProgress(T);
  sl.NotifyAll();
}

void SafepointHandler::EnterSafepointUsingLock(Thread* T) {
  MonitorLocker tl(T->thread_lock());
  T->SetAtSafepoint(true);
  if (T->IsSafepointRequested()) {
    MonitorLocker sl(&safepoint_lock_);
    ASSERT(number_threads_not_at_safepoint_ > 0);
    number_threads_not_at_safepoint_ -= 1;
    sl.Notify();
  }
}

void SafepointHandler::ExitSafepointUsingLock(Thread* T) {
  MonitorLocker tl(T->thread_lock());
  ASSERT(T->IsAtSafepoint());
  while (T->IsSafepointRequested()) {
    T->SetBlockedForSafepoint(true);
    tl.Wait();
    T->SetBlockedForSafepoint(false);
  }
  T->SetAtSafepoint(false);
}

void SafepointHandler::BlockForSafepoint(Thread* T) {
  ASSERT(!T->BypassSafepoints());
  MonitorLocker tl(T->thread_lock());
  if (T->IsSafepointRequested()) {
    T->SetAtSafepoint(true);
    {
      MonitorLocker sl(&safepoint_lock_);
      ASSERT(number_threads_not_at_safepoint_ > 0);
      number_threads_not_at_safepoint_ -= 1;
      sl.Notify();
    }
    while (T->IsSafepointRequested()) {
      T->SetBlockedForSafepoint(true);
      tl.Wait();
      T->SetBlockedForSafepoint(false);
    }
    T->SetAtSafepoint(false);
  }
}

}  // namespace dart
<|endoftext|>


<commit_before>#include <iostream>
#include <type_traits>
#include <vector>

#include <agency/future.hpp>
#include <agency/execution/executor/detail/new_executor_traits.hpp>

#include "test_executors.hpp"

template<class Executor>
void test(Executor exec)
{
  using namespace agency::detail::new_executor_traits_detail;

  auto fut = agency::detail::make_ready_future<int>(7);

  int val = 13;

  using shape_type = executor_shape_t<Executor>;
  using index_type = executor_index_t<Executor>;

  auto f = bulk_then_execute(exec,
    [](index_type idx, int& past_arg, std::vector<int>& results, std::vector<int>& shared_arg)
    {
      results[idx] = past_arg + shared_arg[idx];
    },
    10,
    fut,
    [](shape_type shape){ return std::vector<int>(shape); },     // results
    [](shape_type shape){ return std::vector<int>(shape, 13); }  // shared_arg
  );

  auto result = f.get();

  assert(std::vector<int>(10, 7 + 13) == result);
}

int main()
{
  test(bulk_synchronous_executor());
  test(bulk_asynchronous_executor());
  test(bulk_continuation_executor());

  test(not_a_bulk_synchronous_executor());
  test(not_a_bulk_asynchronous_executor());
  test(not_a_bulk_continuation_executor());

  test(complete_bulk_executor());

  std::cout << "OK" << std::endl;

  return 0;
}

<commit_msg>Eliminate unused variable<commit_after>#include <iostream>
#include <type_traits>
#include <vector>

#include <agency/future.hpp>
#include <agency/execution/executor/detail/new_executor_traits.hpp>

#include "test_executors.hpp"

template<class Executor>
void test(Executor exec)
{
  using namespace agency::detail::new_executor_traits_detail;

  auto fut = agency::detail::make_ready_future<int>(7);

  using shape_type = executor_shape_t<Executor>;
  using index_type = executor_index_t<Executor>;

  auto f = bulk_then_execute(exec,
    [](index_type idx, int& past_arg, std::vector<int>& results, std::vector<int>& shared_arg)
    {
      results[idx] = past_arg + shared_arg[idx];
    },
    10,
    fut,
    [](shape_type shape){ return std::vector<int>(shape); },     // results
    [](shape_type shape){ return std::vector<int>(shape, 13); }  // shared_arg
  );

  auto result = f.get();

  assert(std::vector<int>(10, 7 + 13) == result);
}

int main()
{
  test(bulk_synchronous_executor());
  test(bulk_asynchronous_executor());
  test(bulk_continuation_executor());

  test(not_a_bulk_synchronous_executor());
  test(not_a_bulk_asynchronous_executor());
  test(not_a_bulk_continuation_executor());

  test(complete_bulk_executor());

  std::cout << "OK" << std::endl;

  return 0;
}

<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
//  This utility is designed to be used by the GCC frontend for creating
// bytecode files from it's intermediate llvm assembly.  The requirements for
// this utility are thus slightly different than that of the standard as util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/GCSE.h"
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Transforms/Scalar/InstructionCombining.h"
#include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

cl::String InputFilename ("", "Parse <arg> file, compile to bytecode",
                          cl::Required, "");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
cl::Flag   StopAtLevelRaise("stopraise", "Stop optimization before level raise",
                            cl::Hidden);

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    cerr << E.getMessage() << endl;
    return 1;
  }

  if (M.get() == 0) {
    cerr << "assembly didn't read correctly.\n";
    return 1;
  }

  if (OutputFilename == "") {   // Didn't specify an output filename?
    std::string IFN = InputFilename;
    int Len = IFN.length();
    if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
      OutputFilename = std::string(IFN.begin(), IFN.end()-2);
    } else {
      OutputFilename = IFN;   // Append a .o to it
    }
    OutputFilename += ".o";
  }

  std::ofstream Out(OutputFilename.c_str(), ios::out);
  if (!Out.good()) {
    cerr << "Error opening " << OutputFilename << "!\n";
    return 1;
  }

  // Make sure that the Out file gets unlink'd from the disk if we get a SIGINT
  RemoveFileOnSignal(OutputFilename);

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;
  Passes.add(createFunctionResolvingPass());      // Resolve (...) functions
  Passes.add(createDeadInstEliminationPass());    // Remove Dead code/vars
  Passes.add(createRaiseAllocationsPass());       // call %malloc -> malloc inst
  Passes.add(createCleanupGCCOutputPass());       // Fix gccisms
  Passes.add(createIndVarSimplifyPass());         // Simplify indvars
  if (!StopAtLevelRaise) {
    Passes.add(createRaisePointerReferencesPass()); // Eliminate casts
    Passes.add(createPromoteMemoryToRegister());    // Promote alloca's to regs
    Passes.add(createConstantMergePass());          // Merge dup global consts
    Passes.add(createInstructionCombiningPass());   // Combine silly seq's
    Passes.add(createDeadCodeEliminationPass());    // Remove Dead code/vars
    Passes.add(createGCSEPass());                   // Remove common subexprs
  }
  Passes.add(new WriteBytecodePass(&Out));        // Write bytecode to file...

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());
  return 0;
}

<commit_msg>Move constant merging pass earlier Include the SCCP pass in gccas<commit_after>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
//  This utility is designed to be used by the GCC frontend for creating
// bytecode files from it's intermediate llvm assembly.  The requirements for
// this utility are thus slightly different than that of the standard as util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/Scalar/ConstantProp.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/GCSE.h"
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Transforms/Scalar/InstructionCombining.h"
#include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

cl::String InputFilename ("", "Parse <arg> file, compile to bytecode",
                          cl::Required, "");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
cl::Flag   StopAtLevelRaise("stopraise", "Stop optimization before level raise",
                            cl::Hidden);

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    cerr << E.getMessage() << endl;
    return 1;
  }

  if (M.get() == 0) {
    cerr << "assembly didn't read correctly.\n";
    return 1;
  }

  if (OutputFilename == "") {   // Didn't specify an output filename?
    std::string IFN = InputFilename;
    int Len = IFN.length();
    if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
      OutputFilename = std::string(IFN.begin(), IFN.end()-2);
    } else {
      OutputFilename = IFN;   // Append a .o to it
    }
    OutputFilename += ".o";
  }

  std::ofstream Out(OutputFilename.c_str(), ios::out);
  if (!Out.good()) {
    cerr << "Error opening " << OutputFilename << "!\n";
    return 1;
  }

  // Make sure that the Out file gets unlink'd from the disk if we get a SIGINT
  RemoveFileOnSignal(OutputFilename);

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;
  Passes.add(createFunctionResolvingPass());      // Resolve (...) functions
  Passes.add(createConstantMergePass());          // Merge dup global constants
  Passes.add(createDeadInstEliminationPass());    // Remove Dead code/vars
  Passes.add(createRaiseAllocationsPass());       // call %malloc -> malloc inst
  Passes.add(createCleanupGCCOutputPass());       // Fix gccisms
  Passes.add(createIndVarSimplifyPass());         // Simplify indvars
  if (!StopAtLevelRaise) {
    Passes.add(createRaisePointerReferencesPass()); // Eliminate casts
    Passes.add(createPromoteMemoryToRegister());    // Promote alloca's to regs
    Passes.add(createInstructionCombiningPass());   // Combine silly seq's
    Passes.add(createDeadCodeEliminationPass());    // Remove Dead code/vars
    Passes.add(createSCCPPass());                   // Constant prop with SCCP
    Passes.add(createGCSEPass());                   // Remove common subexprs
  }
  Passes.add(new WriteBytecodePass(&Out));        // Write bytecode to file...

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());
  return 0;
}

<|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Authenticator.h"
#include "OSSupport/BlockingTCPLink.h"
#include "Root.h"
#include "Server.h"

#include "../lib/iniFile/iniFile.h"

#include <sstream>

#define DEFAULT_AUTH_SERVER "session.minecraft.net"
#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%"
#define MAX_REDIRECTS 10

cAuthenticator::cAuthenticator(void) :
	super("cAuthenticator"),
	m_Server(DEFAULT_AUTH_SERVER),
	m_Address(DEFAULT_AUTH_ADDRESS),
	m_ShouldAuthenticate(true)
{
}

cAuthenticator::~cAuthenticator()
{
	Stop();
}

/// Read custom values from INI
void cAuthenticator::ReadINI(cIniFile & IniFile)
{
	m_Server  = IniFile.GetValueSet("Authentication", "Server", DEFAULT_AUTH_SERVER);
	m_Address = IniFile.GetValueSet("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
	m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
}

/// Queues a request for authenticating a user. If the auth fails, the user is kicked
void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
{
	if (!m_ShouldAuthenticate)
	{
		cRoot::Get()->AuthenticateUser(a_ClientID);
		return;
	}

	cCSLock Lock(m_CS);
	m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
	m_QueueNonempty.Set();
}

void cAuthenticator::Start(cIniFile & IniFile)
{
	ReadINI(IniFile);
	m_ShouldTerminate = false;
	super::Start();
}

void cAuthenticator::Stop(void)
{
	m_ShouldTerminate = true;
	m_QueueNonempty.Set();
	Wait();
}

void cAuthenticator::Execute(void)
{
	for (;;)
	{
		cCSLock Lock(m_CS);
		while (!m_ShouldTerminate && (m_Queue.size() == 0))
		{
			cCSUnlock Unlock(Lock);
			m_QueueNonempty.Wait();
		}
		if (m_ShouldTerminate)
		{
			return;
		}
		ASSERT(!m_Queue.empty());

		int ClientID = m_Queue.front().m_ClientID;
		AString UserName = m_Queue.front().m_Name;
		AString ActualAddress = m_Address;
		ReplaceString(ActualAddress, "%USERNAME%", UserName);
		ReplaceString(ActualAddress, "%SERVERID%", m_Queue.front().m_ServerID);
		m_Queue.pop_front();
		Lock.Unlock();

		if (!AuthFromAddress(m_Server, ActualAddress, UserName))
		{
			cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
		}
		else
		{
			cRoot::Get()->AuthenticateUser(ClientID);
		}
	}  // for (-ever)
}

bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */)
{
	// Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)

	cBlockingTCPLink Link;
	if (!Link.Connect(a_Server.c_str(), 80))
	{
		LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str());
		return false;
	}

	Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.1\r\n" ).c_str());
	Link.SendMessage( AString( "User-Agent: MCServer\r\n" ).c_str());
	Link.SendMessage( AString( "Host: " + a_Server + "\r\n" ).c_str());
	//Link.SendMessage( AString( "Host: session.minecraft.net\r\n" ).c_str());
	Link.SendMessage( AString( "Accept: */*\r\n" ).c_str());
	Link.SendMessage( AString( "Connection: close\r\n" ).c_str());	//Close so we dont have to mess with the Content-Length :)
	Link.SendMessage( AString( "\r\n" ).c_str());
	AString DataRecvd;
	Link.ReceiveData(DataRecvd);
	Link.CloseSocket();

	std::stringstream ss(DataRecvd);

	// Parse the data received:
	std::string temp;
	ss >> temp;
	bool bRedirect = false;
	bool bOK = false;
	if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0))
	{
		int code;
		ss >> code;
		if (code == 302)
		{
			// redirect blabla
			LOGINFO("Need to redirect!");
			if (a_Level > MAX_REDIRECTS)
			{
				LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str());
				return false;
			}
			bRedirect = true;
		}
		else if (code == 200)
		{
			LOGD("cAuthenticator: Received status 200 OK! :D");
			bOK = true;
		}
	}
	else
	{
		LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	if( bRedirect )
	{
		AString Location;
		// Search for "Location:"
		bool bFoundLocation = false;
		while( !bFoundLocation && ss.good() )
		{
			char c = 0;
			while( c != '\n' )
			{
				ss.get( c );
			}
			AString Name;
			ss >> Name;
			if (Name.compare("Location:") == 0)
			{
				bFoundLocation = true;
				ss >> Location;
			}
		}
		if (!bFoundLocation)
		{
			LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
			return false;
		}

		Location = Location.substr(strlen("http://"), std::string::npos); // Strip http://
		std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address
		Location = Location.substr( Server.length(), std::string::npos);
		return AuthFromAddress(Server, Location, a_UserName, a_Level + 1);
	}

	if (!bOK)
	{
		LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	// Header says OK, so receive the rest.
	// Go past header, double \n means end of headers
	char c = 0;
	while (ss.good())
	{
		while (c != '\n')
		{
			ss.get(c);
		}
		ss.get(c);
		if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' )
			break;
	}
	if (!ss.good())
	{
		LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	std::string Result;
	ss >> Result;
	LOGD("cAuthenticator: Authentication result was %s", Result.c_str());

	if (Result.compare("YES") == 0)	//Works well
	{
		LOGINFO("Authentication result \"YES\", player authentication success!");
		return true;
	}

	LOGINFO("Authentication result was \"%s\", player authentication failure!", Result.c_str());
	return false;
}

<commit_msg>And another.<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Authenticator.h"
#include "OSSupport/BlockingTCPLink.h"
#include "Root.h"
#include "Server.h"

#include ".inifile/iniFile.h"

#include <sstream>

#define DEFAULT_AUTH_SERVER "session.minecraft.net"
#define DEFAULT_AUTH_ADDRESS "/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%"
#define MAX_REDIRECTS 10

cAuthenticator::cAuthenticator(void) :
	super("cAuthenticator"),
	m_Server(DEFAULT_AUTH_SERVER),
	m_Address(DEFAULT_AUTH_ADDRESS),
	m_ShouldAuthenticate(true)
{
}

cAuthenticator::~cAuthenticator()
{
	Stop();
}

/// Read custom values from INI
void cAuthenticator::ReadINI(cIniFile & IniFile)
{
	m_Server  = IniFile.GetValueSet("Authentication", "Server", DEFAULT_AUTH_SERVER);
	m_Address = IniFile.GetValueSet("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
	m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
}

/// Queues a request for authenticating a user. If the auth fails, the user is kicked
void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash)
{
	if (!m_ShouldAuthenticate)
	{
		cRoot::Get()->AuthenticateUser(a_ClientID);
		return;
	}

	cCSLock Lock(m_CS);
	m_Queue.push_back(cUser(a_ClientID, a_UserName, a_ServerHash));
	m_QueueNonempty.Set();
}

void cAuthenticator::Start(cIniFile & IniFile)
{
	ReadINI(IniFile);
	m_ShouldTerminate = false;
	super::Start();
}

void cAuthenticator::Stop(void)
{
	m_ShouldTerminate = true;
	m_QueueNonempty.Set();
	Wait();
}

void cAuthenticator::Execute(void)
{
	for (;;)
	{
		cCSLock Lock(m_CS);
		while (!m_ShouldTerminate && (m_Queue.size() == 0))
		{
			cCSUnlock Unlock(Lock);
			m_QueueNonempty.Wait();
		}
		if (m_ShouldTerminate)
		{
			return;
		}
		ASSERT(!m_Queue.empty());

		int ClientID = m_Queue.front().m_ClientID;
		AString UserName = m_Queue.front().m_Name;
		AString ActualAddress = m_Address;
		ReplaceString(ActualAddress, "%USERNAME%", UserName);
		ReplaceString(ActualAddress, "%SERVERID%", m_Queue.front().m_ServerID);
		m_Queue.pop_front();
		Lock.Unlock();

		if (!AuthFromAddress(m_Server, ActualAddress, UserName))
		{
			cRoot::Get()->KickUser(ClientID, "Failed to authenticate account!");
		}
		else
		{
			cRoot::Get()->AuthenticateUser(ClientID);
		}
	}  // for (-ever)
}

bool cAuthenticator::AuthFromAddress(const AString & a_Server, const AString & a_Address, const AString & a_UserName, int a_Level /* = 1 */)
{
	// Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep)

	cBlockingTCPLink Link;
	if (!Link.Connect(a_Server.c_str(), 80))
	{
		LOGERROR("cAuthenticator: cannot connect to auth server \"%s\", kicking user \"%s\"", a_Server.c_str(), a_Server.c_str());
		return false;
	}

	Link.SendMessage( AString( "GET " + a_Address + " HTTP/1.1\r\n" ).c_str());
	Link.SendMessage( AString( "User-Agent: MCServer\r\n" ).c_str());
	Link.SendMessage( AString( "Host: " + a_Server + "\r\n" ).c_str());
	//Link.SendMessage( AString( "Host: session.minecraft.net\r\n" ).c_str());
	Link.SendMessage( AString( "Accept: */*\r\n" ).c_str());
	Link.SendMessage( AString( "Connection: close\r\n" ).c_str());	//Close so we dont have to mess with the Content-Length :)
	Link.SendMessage( AString( "\r\n" ).c_str());
	AString DataRecvd;
	Link.ReceiveData(DataRecvd);
	Link.CloseSocket();

	std::stringstream ss(DataRecvd);

	// Parse the data received:
	std::string temp;
	ss >> temp;
	bool bRedirect = false;
	bool bOK = false;
	if ((temp.compare("HTTP/1.1") == 0) || (temp.compare("HTTP/1.0") == 0))
	{
		int code;
		ss >> code;
		if (code == 302)
		{
			// redirect blabla
			LOGINFO("Need to redirect!");
			if (a_Level > MAX_REDIRECTS)
			{
				LOGERROR("cAuthenticator: received too many levels of redirection from auth server \"%s\" for user \"%s\", bailing out and kicking the user", a_Server.c_str(), a_UserName.c_str());
				return false;
			}
			bRedirect = true;
		}
		else if (code == 200)
		{
			LOGD("cAuthenticator: Received status 200 OK! :D");
			bOK = true;
		}
	}
	else
	{
		LOGERROR("cAuthenticator: cannot parse auth reply from server \"%s\" for user \"%s\", kicking the user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	if( bRedirect )
	{
		AString Location;
		// Search for "Location:"
		bool bFoundLocation = false;
		while( !bFoundLocation && ss.good() )
		{
			char c = 0;
			while( c != '\n' )
			{
				ss.get( c );
			}
			AString Name;
			ss >> Name;
			if (Name.compare("Location:") == 0)
			{
				bFoundLocation = true;
				ss >> Location;
			}
		}
		if (!bFoundLocation)
		{
			LOGERROR("cAuthenticator: received invalid redirection from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
			return false;
		}

		Location = Location.substr(strlen("http://"), std::string::npos); // Strip http://
		std::string Server = Location.substr( 0, Location.find( "/" ) ); // Only leave server address
		Location = Location.substr( Server.length(), std::string::npos);
		return AuthFromAddress(Server, Location, a_UserName, a_Level + 1);
	}

	if (!bOK)
	{
		LOGERROR("cAuthenticator: received an error from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	// Header says OK, so receive the rest.
	// Go past header, double \n means end of headers
	char c = 0;
	while (ss.good())
	{
		while (c != '\n')
		{
			ss.get(c);
		}
		ss.get(c);
		if( c == '\n' || c == '\r' || ss.peek() == '\r' || ss.peek() == '\n' )
			break;
	}
	if (!ss.good())
	{
		LOGERROR("cAuthenticator: error while parsing response body from auth server \"%s\" for user \"%s\", kicking user.", a_Server.c_str(), a_UserName.c_str());
		return false;
	}

	std::string Result;
	ss >> Result;
	LOGD("cAuthenticator: Authentication result was %s", Result.c_str());

	if (Result.compare("YES") == 0)	//Works well
	{
		LOGINFO("Authentication result \"YES\", player authentication success!");
		return true;
	}

	LOGINFO("Authentication result was \"%s\", player authentication failure!", Result.c_str());
	return false;
}

<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH

#include <vector>
#include <type_traits>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interface.hh>

#include <dune/gdt/space/interface.hh>
#include <dune/gdt/mapper/interface.hh>

namespace Dune {
namespace GDT {

template <class VectorImp>
class ConstLocalDoFVector
{
  static_assert(std::is_base_of<Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");

public:
  typedef VectorImp VectorType;
  typedef typename VectorType::ElementType ElementType;

  template <class M, class EntityType>
  ConstLocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, const VectorType& vector)
    : vector_(vector)
    , indices_(mapper.numDofs(entity))
  {
    mapper.globalIndices(entity, indices_);
  }

  ~ConstLocalDoFVector()
  {
  }

  size_t size() const
  {
    return indices_.size();
  }

  ElementType get(const size_t ii) const
  {
    assert(ii < indices_.size());
    return vector_.get(indices_[ii]);
  }

private:
  const VectorType& vector_;

protected:
  mutable Dune::DynamicVector<size_t> indices_;
}; // class ConstLocalDoFVector

template <class VectorImp>
class LocalDoFVector : public ConstLocalDoFVector<VectorImp>
{
  typedef ConstLocalDoFVector<VectorImp> BaseType;

public:
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;

  template <class M, class EntityType>
  LocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, VectorType& vector)
    : BaseType(mapper, entity, vector)
    , vector_(vector)
  {
  }

  ~LocalDoFVector()
  {
  }

  void set(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.set(indices_[ii], val);
  }

  void add(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.add(indices_[ii], val);
  }

private:
  using BaseType::indices_;
  VectorType& vector_;
}; // class LocalDoFVector

template <class SpaceImp, class VectorImp>
class ConstLocalDiscreteFunction
    : public Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                           SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                           SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ElementType>::value,
                "Types do not match!");
  typedef Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                        SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                        SpaceImp::dimRangeCols> BaseType;
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef ConstLocalDoFVector<VectorType> ConstLocalDoFVectorType;

  ConstLocalDiscreteFunction(const SpaceType& space, const VectorType& globalVector, const EntityType& ent)
    : space_(space)
    , entity_(ent)
    , base_(new BaseFunctionSetType(space_.baseFunctionSet(entity_)))
    , localVector_(new ConstLocalDoFVectorType(space_.mapper(), entity_, globalVector))
    , tmpBaseValues_(base_->size(), RangeType(0))
    , tmpBaseJacobianValues_(base_->size(), JacobianRangeType(0))
  {
    assert(localVector_->size() == base_->size());
  }

  ConstLocalDiscreteFunction(ThisType&& source)
    : space_(source.space_)
    , entity_(source.entity_)
    , base_(std::move(source.base_))
    , localVector_(std::move(source.localVector_))
    , tmpBaseValues_(std::move(source.tmpBaseValues_))
    , tmpBaseJacobianValues_(std::move(source.tmpBaseJacobianValues_))
  {
  }

  ConstLocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~ConstLocalDiscreteFunction()
  {
  }

  virtual const EntityType& entity() const override
  {
    return entity_;
  }

  const ConstLocalDoFVectorType& vector() const
  {
    return *localVector_;
  }

  virtual size_t order() const override
  {
    return base_->order();
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const override
  {
    assert(this->is_a_valid_point(xx));
    Dune::Stuff::Common::clear(ret);
    assert(localVector_->size() == tmpBaseValues_.size());
    base_->evaluate(xx, tmpBaseValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseValues_[ii];
    }
  } // ... evaluate(...)

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const override
  {
    assert(this->is_a_valid_point(xx));
    Dune::Stuff::Common::clear(ret);
    assert(localVector_->size() == tmpBaseJacobianValues_.size());
    base_->jacobian(xx, tmpBaseJacobianValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseJacobianValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseJacobianValues_[ii];
    }
  } // ... jacobian(...)

protected:
  const SpaceType& space_;
  const EntityType& entity_;
  std::unique_ptr<const BaseFunctionSetType> base_;
  std::unique_ptr<const ConstLocalDoFVectorType> localVector_;

private:
  mutable std::vector<RangeType> tmpBaseValues_;
  mutable std::vector<JacobianRangeType> tmpBaseJacobianValues_;
}; // class ConstLocalDiscreteFunction

template <class SpaceImp, class VectorImp>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef LocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef LocalDoFVector<VectorType> LocalDoFVectorType;

  LocalDiscreteFunction(const SpaceType& space, VectorType& globalVector, const EntityType& ent)
    : BaseType(space, globalVector, ent)
    , localVector_(new LocalDoFVectorType(space_.mapper(), entity_, globalVector))
  {
    assert(localVector_->size() == base_->size());
  }

  LocalDiscreteFunction(ThisType&& source)
    : BaseType(std::move(source))
    , localVector_(std::move(source.localVector_)) // <- I am not sure if this is valid
  {
  }

  LocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~LocalDiscreteFunction()
  {
  }

  LocalDoFVectorType& vector()
  {
    return *localVector_;
  }

private:
  using BaseType::space_;
  using BaseType::entity_;
  using BaseType::base_;
  std::unique_ptr<LocalDoFVectorType> localVector_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
<commit_msg>[discretefunction.local] clear by *= 0<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH

#include <vector>
#include <type_traits>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interface.hh>

#include <dune/gdt/space/interface.hh>
#include <dune/gdt/mapper/interface.hh>

namespace Dune {
namespace GDT {

template <class VectorImp>
class ConstLocalDoFVector
{
  static_assert(std::is_base_of<Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");

public:
  typedef VectorImp VectorType;
  typedef typename VectorType::ElementType ElementType;

  template <class M, class EntityType>
  ConstLocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, const VectorType& vector)
    : vector_(vector)
    , indices_(mapper.numDofs(entity))
  {
    mapper.globalIndices(entity, indices_);
  }

  ~ConstLocalDoFVector()
  {
  }

  size_t size() const
  {
    return indices_.size();
  }

  ElementType get(const size_t ii) const
  {
    assert(ii < indices_.size());
    return vector_.get(indices_[ii]);
  }

private:
  const VectorType& vector_;

protected:
  mutable Dune::DynamicVector<size_t> indices_;
}; // class ConstLocalDoFVector

template <class VectorImp>
class LocalDoFVector : public ConstLocalDoFVector<VectorImp>
{
  typedef ConstLocalDoFVector<VectorImp> BaseType;

public:
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;

  template <class M, class EntityType>
  LocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, VectorType& vector)
    : BaseType(mapper, entity, vector)
    , vector_(vector)
  {
  }

  ~LocalDoFVector()
  {
  }

  void set(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.set(indices_[ii], val);
  }

  void add(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.add(indices_[ii], val);
  }

private:
  using BaseType::indices_;
  VectorType& vector_;
}; // class LocalDoFVector

template <class SpaceImp, class VectorImp>
class ConstLocalDiscreteFunction
    : public Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                           SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                           SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ElementType>::value,
                "Types do not match!");
  typedef Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                        SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                        SpaceImp::dimRangeCols> BaseType;
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef ConstLocalDoFVector<VectorType> ConstLocalDoFVectorType;

  ConstLocalDiscreteFunction(const SpaceType& space, const VectorType& globalVector, const EntityType& ent)
    : space_(space)
    , entity_(ent)
    , base_(new BaseFunctionSetType(space_.baseFunctionSet(entity_)))
    , localVector_(new ConstLocalDoFVectorType(space_.mapper(), entity_, globalVector))
    , tmpBaseValues_(base_->size(), RangeType(0))
    , tmpBaseJacobianValues_(base_->size(), JacobianRangeType(0))
  {
    assert(localVector_->size() == base_->size());
  }

  ConstLocalDiscreteFunction(ThisType&& source)
    : space_(source.space_)
    , entity_(source.entity_)
    , base_(std::move(source.base_))
    , localVector_(std::move(source.localVector_))
    , tmpBaseValues_(std::move(source.tmpBaseValues_))
    , tmpBaseJacobianValues_(std::move(source.tmpBaseJacobianValues_))
  {
  }

  ConstLocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~ConstLocalDiscreteFunction()
  {
  }

  virtual const EntityType& entity() const override
  {
    return entity_;
  }

  const ConstLocalDoFVectorType& vector() const
  {
    return *localVector_;
  }

  virtual size_t order() const override
  {
    return base_->order();
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const override
  {
    assert(this->is_a_valid_point(xx));
    Dune::Stuff::Common::clear(ret);
    assert(localVector_->size() == tmpBaseValues_.size());
    base_->evaluate(xx, tmpBaseValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseValues_[ii];
    }
  } // ... evaluate(...)

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const override
  {
    assert(this->is_a_valid_point(xx));
    ret *= RangeFieldType(0);
    assert(localVector_->size() == tmpBaseJacobianValues_.size());
    base_->jacobian(xx, tmpBaseJacobianValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseJacobianValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseJacobianValues_[ii];
    }
  } // ... jacobian(...)

protected:
  const SpaceType& space_;
  const EntityType& entity_;
  std::unique_ptr<const BaseFunctionSetType> base_;
  std::unique_ptr<const ConstLocalDoFVectorType> localVector_;

private:
  mutable std::vector<RangeType> tmpBaseValues_;
  mutable std::vector<JacobianRangeType> tmpBaseJacobianValues_;
}; // class ConstLocalDiscreteFunction

template <class SpaceImp, class VectorImp>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef LocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef LocalDoFVector<VectorType> LocalDoFVectorType;

  LocalDiscreteFunction(const SpaceType& space, VectorType& globalVector, const EntityType& ent)
    : BaseType(space, globalVector, ent)
    , localVector_(new LocalDoFVectorType(space_.mapper(), entity_, globalVector))
  {
    assert(localVector_->size() == base_->size());
  }

  LocalDiscreteFunction(ThisType&& source)
    : BaseType(std::move(source))
    , localVector_(std::move(source.localVector_)) // <- I am not sure if this is valid
  {
  }

  LocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~LocalDiscreteFunction()
  {
  }

  LocalDoFVectorType& vector()
  {
    return *localVector_;
  }

private:
  using BaseType::space_;
  using BaseType::entity_;
  using BaseType::base_;
  std::unique_ptr<LocalDoFVectorType> localVector_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
<|endoftext|>


<commit_before>#include "schedulers/shortest_path_switch_scheduler.h"

DEFINE_bool(overtake, true, "Should car overtake others?");

// TODO refactor whole code here, its copypaste

using game::Position;

namespace schedulers {

ShortestPathSwitchScheduler::ShortestPathSwitchScheduler(
    const game::Race& race,
    game::RaceTracker& race_tracker,
    game::CarTracker& car_tracker)
  : race_(race), car_tracker_(car_tracker), race_tracker_(race_tracker),
    should_switch_now_(false), waiting_for_switch_(false),
    target_switch_(-1) {
  //ComputeShortestPaths();
}

// Prepares for overtake
void ShortestPathSwitchScheduler::Overtake(const string& color) {
  printf("Feature not implemented\n");
}

// Updates the state and calculates next state
// TODO switch time
void ShortestPathSwitchScheduler::Schedule(const game::CarState& state) {
  if (state.position().piece() == target_switch_) {
    waiting_for_switch_ = false;
    target_switch_ = -1;
  }
  if (waiting_for_switch_)
    return;

  // TODO its greedy :D
  const Position& position = state.position();

  // We evaluate next two switches to decide if we should change the lane.
  int from = race_.track().NextSwitch(position.piece());
  int to = race_.track().NextSwitch(from);

  // Distance between current position and the 'to' switch:
  // - if we stay on current lane
  // - if we decide to switch to left lane
  // - if we decide to switch to right lane
  Position end_position;
  end_position.set_piece(to);
  double current = DistanceBetween(position, end_position, position.end_lane());
  double left = DistanceBetween(position, end_position, position.end_lane() - 1);
  double right = DistanceBetween(position, end_position, position.end_lane() + 1);

  // TODO(tomek) Improve:
  // - we should "score" every lane, based on opponents on them
  // - even if someone has very good lap, he can crashed and respawned
  // - consider instead of distance, trying to estimate how much time
  //   it will take us to drive through given lanes

  // Overtaking
  if (FLAGS_overtake) {
    int left_score = race_tracker_.ScoreLane(from, to, position.end_lane() - 1);
    int right_score = race_tracker_.ScoreLane(from, to, position.end_lane() + 1);
    int current_score = race_tracker_.ScoreLane(from, to, position.end_lane());

    if (left_score < 0) left = kInf;
    if (right_score < 0) right = kInf;
    if (current_score < 0) current = kInf;

    // Score is <-10, 0), 0 is best
    // Nest part of algorithm chooses smallest so we need to reverse it temporarily
    if (left_score < 0 && current_score < 0 && right_score < 0) {
      left = -left_score;
      current = -current_score;
      right = -current_score;
    }
  }

  printf("%lf %lf %lf\n",left, current, right);

  if (left < current && left < right) {
    scheduled_switch_ = game::Switch::kSwitchLeft;
    target_switch_ = from;
    should_switch_now_ = true;
  } else if (right < current && right <= left) {
    scheduled_switch_ = game::Switch::kSwitchRight;
    target_switch_ = from;
    should_switch_now_ = true;
  } else {
    should_switch_now_ = false;
    target_switch_ = -1;
  }
}

double ShortestPathSwitchScheduler::DistanceBetween(const Position& position1, const Position& position2, int lane) {
  if (!race_.track().IsLaneCorrect(lane)) {
    return kInf;
  }
  Position end_position = position2;
  end_position.set_start_lane(lane);
  end_position.set_end_lane(lane);

  return car_tracker_.DistanceBetween(position1, end_position);
}

void ShortestPathSwitchScheduler::ComputeShortestPaths() {
  // TODO
}

void ShortestPathSwitchScheduler::Switched() {
  should_switch_now_ = false;
  waiting_for_switch_ = true;
}

// Returns scheduled switch
bool ShortestPathSwitchScheduler::ShouldSwitch() {
  if (should_switch_now_ &&
      !waiting_for_switch_) {
    auto s = car_tracker_.current_state();
    s = car_tracker_.Predict(s, game::Command(1));
    s = car_tracker_.Predict(s, game::Command(1));
    if (s.position().piece() != target_switch_)
      return false;

    if (car_tracker_.current_state().velocity() > 0 &&
        car_tracker_.IsSafe(car_tracker_.current_state(), game::Command(scheduled_switch_)))
      return true;
  }
  return false;
}

game::Switch ShortestPathSwitchScheduler::ExpectedSwitch() {
  if (should_switch_now_ && !waiting_for_switch_)
    return scheduled_switch_;
  return game::Switch::kStay;
}

game::Switch ShortestPathSwitchScheduler::SwitchDirection() {
  return scheduled_switch_;
}

}  // namespace schedulers
<commit_msg>Improve log<commit_after>#include "schedulers/shortest_path_switch_scheduler.h"

DEFINE_bool(overtake, true, "Should car overtake others?");

// TODO refactor whole code here, its copypaste

using game::Position;

namespace schedulers {

ShortestPathSwitchScheduler::ShortestPathSwitchScheduler(
    const game::Race& race,
    game::RaceTracker& race_tracker,
    game::CarTracker& car_tracker)
  : race_(race), car_tracker_(car_tracker), race_tracker_(race_tracker),
    should_switch_now_(false), waiting_for_switch_(false),
    target_switch_(-1) {
  //ComputeShortestPaths();
}

// Prepares for overtake
void ShortestPathSwitchScheduler::Overtake(const string& color) {
  printf("Feature not implemented\n");
}

// Updates the state and calculates next state
// TODO switch time
void ShortestPathSwitchScheduler::Schedule(const game::CarState& state) {
  if (state.position().piece() == target_switch_) {
    waiting_for_switch_ = false;
    target_switch_ = -1;
  }
  if (waiting_for_switch_)
    return;

  // TODO its greedy :D
  const Position& position = state.position();

  // We evaluate next two switches to decide if we should change the lane.
  int from = race_.track().NextSwitch(position.piece());
  int to = race_.track().NextSwitch(from);

  // Distance between current position and the 'to' switch:
  // - if we stay on current lane
  // - if we decide to switch to left lane
  // - if we decide to switch to right lane
  Position end_position;
  end_position.set_piece(to);
  double current = DistanceBetween(position, end_position, position.end_lane());
  double left = DistanceBetween(position, end_position, position.end_lane() - 1);
  double right = DistanceBetween(position, end_position, position.end_lane() + 1);

  // TODO(tomek) Improve:
  // - we should "score" every lane, based on opponents on them
  // - even if someone has very good lap, he can crashed and respawned
  // - consider instead of distance, trying to estimate how much time
  //   it will take us to drive through given lanes

  // Overtaking
  if (FLAGS_overtake) {
    int left_score = race_tracker_.ScoreLane(from, to, position.end_lane() - 1);
    int right_score = race_tracker_.ScoreLane(from, to, position.end_lane() + 1);
    int current_score = race_tracker_.ScoreLane(from, to, position.end_lane());

    if (left_score < 0) left = kInf;
    if (right_score < 0) right = kInf;
    if (current_score < 0) current = kInf;

    // Score is <-10, 0), 0 is best
    // Nest part of algorithm chooses smallest so we need to reverse it temporarily
    if (left_score < 0 && current_score < 0 && right_score < 0) {
      left = -left_score;
      current = -current_score;
      right = -current_score;
    }
  }

  printf("Lane scores (l c r): %lf %lf %lf\n",left, current, right);

  if (left < current && left < right) {
    scheduled_switch_ = game::Switch::kSwitchLeft;
    target_switch_ = from;
    should_switch_now_ = true;
  } else if (right < current && right <= left) {
    scheduled_switch_ = game::Switch::kSwitchRight;
    target_switch_ = from;
    should_switch_now_ = true;
  } else {
    should_switch_now_ = false;
    target_switch_ = -1;
  }
}

double ShortestPathSwitchScheduler::DistanceBetween(const Position& position1, const Position& position2, int lane) {
  if (!race_.track().IsLaneCorrect(lane)) {
    return kInf;
  }
  Position end_position = position2;
  end_position.set_start_lane(lane);
  end_position.set_end_lane(lane);

  return car_tracker_.DistanceBetween(position1, end_position);
}

void ShortestPathSwitchScheduler::ComputeShortestPaths() {
  // TODO
}

void ShortestPathSwitchScheduler::Switched() {
  should_switch_now_ = false;
  waiting_for_switch_ = true;
}

// Returns scheduled switch
bool ShortestPathSwitchScheduler::ShouldSwitch() {
  if (should_switch_now_ &&
      !waiting_for_switch_) {
    auto s = car_tracker_.current_state();
    s = car_tracker_.Predict(s, game::Command(1));
    s = car_tracker_.Predict(s, game::Command(1));
    if (s.position().piece() != target_switch_)
      return false;

    if (car_tracker_.current_state().velocity() > 0 &&
        car_tracker_.IsSafe(car_tracker_.current_state(), game::Command(scheduled_switch_)))
      return true;
  }
  return false;
}

game::Switch ShortestPathSwitchScheduler::ExpectedSwitch() {
  if (should_switch_now_ && !waiting_for_switch_)
    return scheduled_switch_;
  return game::Switch::kStay;
}

game::Switch ShortestPathSwitchScheduler::SwitchDirection() {
  return scheduled_switch_;
}

}  // namespace schedulers
<|endoftext|>


<commit_before>/** @file propertyeditorproxymodel.cpp
 *	@brief Модель редактора свойств
 * */
#include <QDebug>

#include "propertyeditorproxymodel.h"
#include "realreporoles.h"

PropertyEditorModel::PropertyEditorModel(QObject *parent)
	: QAbstractTableModel(parent), type(""), mPseudoAttributesCount(0)
{
}

int PropertyEditorModel::rowCount(const QModelIndex&) const
{
	return roleNames.size();
}

int PropertyEditorModel::columnCount(const QModelIndex&) const
{
	return 2;
}

Qt::ItemFlags PropertyEditorModel::flags (const QModelIndex &index) const
{
	// Property names
	if (index.column() == 0)
		return Qt::ItemIsEnabled;

	// Object id
	if (index.row() < mPseudoAttributesCount)
		return Qt::NoItemFlags;

	// Other properties
	return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}

QVariant PropertyEditorModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//	if ( ! targetModel )
//		return QVariant();

	if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
		return QString(section ? "value" : "name");
	else
		return QVariant();
}

QVariant PropertyEditorModel::data(const QModelIndex &index, int role) const
{
//	if ( ! targetModel )
//		return QVariant();

	if (role != Qt::DisplayRole)
		return QVariant();

	if (index.column() == 0) {
		return roleNames.at(index.row());
	} else if (index.column() == 1) {
		if (index.row() != 0)
			return targetObject.data(info.roleByIndex(index.row() - mPseudoAttributesCount));
		else
			return QVariant(type);
	} else
		return QVariant();
}

bool PropertyEditorModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	bool ret;

	if ( ! targetModel )
		return false;

	if ( ( role == Qt::DisplayRole || role == Qt::EditRole ) && index.column() == 1 )
		if (index.row() != 0)
			ret = targetModel->setData(targetObject, value, info.roleByIndex(index.row() - mPseudoAttributesCount));
		else
			ret = true;
	else
		ret = false;
	if (ret)
		dataChanged(index, index);
	return ret;
}

void PropertyEditorModel::rereadData()
{
	reset();
}

void PropertyEditorModel::setSourceModel(QAbstractItemModel *sourceModel)
{
	targetModel = sourceModel;

	roleNames.clear();

	if ( targetModel )
		connect ( targetModel, SIGNAL( dataChanged (const QModelIndex &, const QModelIndex&) ),
				this, SLOT( rereadData() ) );

	reset();
}

void PropertyEditorModel::setIndex(const QModelIndex &sourceIndex)
{
	if ( sourceIndex.model() != targetModel )
		return;

	targetObject = sourceIndex;
	type = targetObject.data(Unreal::TypeRole).toString();

	roleNames = info.getColumnNames(type);

	roleNames.push_front("metatype");
	mPseudoAttributesCount = 1;

	reset();
}
<commit_msg>Фикс к #126.<commit_after>/** @file propertyeditorproxymodel.cpp
 *	@brief Модель редактора свойств
 * */
#include <QDebug>

#include "propertyeditorproxymodel.h"
#include "realreporoles.h"

PropertyEditorModel::PropertyEditorModel(QObject *parent)
	: QAbstractTableModel(parent), type(""), mPseudoAttributesCount(0)
{
}

int PropertyEditorModel::rowCount(const QModelIndex&) const
{
	return roleNames.size();
}

int PropertyEditorModel::columnCount(const QModelIndex&) const
{
	return 2;
}

Qt::ItemFlags PropertyEditorModel::flags (const QModelIndex &index) const
{
	// Property names
	if (index.column() == 0)
		return Qt::ItemIsEnabled;

	// Object id
	if (index.row() < mPseudoAttributesCount)
		return Qt::NoItemFlags;

	// Other properties
	return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}

QVariant PropertyEditorModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//	if ( ! targetModel )
//		return QVariant();

	if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
		return QString(section ? "value" : "name");
	else
		return QVariant();
}

QVariant PropertyEditorModel::data(const QModelIndex &index, int role) const
{
//	if ( ! targetModel )
//		return QVariant();

	if (role != Qt::DisplayRole)
		return QVariant();

	if (index.column() == 0) {
		return roleNames.at(index.row());
	} else if (index.column() == 1) {
		if (index.row() >= mPseudoAttributesCount)
			return targetObject.data(info.roleByIndex(index.row() - mPseudoAttributesCount));
		else if (index.row() == 0)
			return QVariant(type);
		else
			return targetObject.data(Unreal::IdRole);
	} else
		return QVariant();
}

bool PropertyEditorModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	bool ret;

	if ( ! targetModel )
		return false;

	if ( ( role == Qt::DisplayRole || role == Qt::EditRole ) && index.column() == 1 )
		if (index.row() != 0)
			ret = targetModel->setData(targetObject, value, info.roleByIndex(index.row() - mPseudoAttributesCount));
		else
			ret = true;
	else
		ret = false;
	if (ret)
		dataChanged(index, index);
	return ret;
}

void PropertyEditorModel::rereadData()
{
	reset();
}

void PropertyEditorModel::setSourceModel(QAbstractItemModel *sourceModel)
{
	targetModel = sourceModel;

	roleNames.clear();

	if ( targetModel )
		connect ( targetModel, SIGNAL( dataChanged (const QModelIndex &, const QModelIndex&) ),
				this, SLOT( rereadData() ) );

	reset();
}

void PropertyEditorModel::setIndex(const QModelIndex &sourceIndex)
{
	if ( sourceIndex.model() != targetModel )
		return;

	targetObject = sourceIndex;
	type = targetObject.data(Unreal::TypeRole).toString();

	roleNames = info.getColumnNames(type);

	roleNames.push_front("repo_id");
	roleNames.push_front("metatype");
	mPseudoAttributesCount = 2;

	reset();
}
<|endoftext|>