<commit_before>///
/// @file  pi_lmo_simple.cpp
/// @brief Simple demonstration implementation of the
///        Lagarias-Miller-Odlyzko prime counting algorithm.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "imath.h"
#include "Pk.h"
#include "phi.h"

#include <primesieve/soe/PrimeSieve.h>
#include <primecount.h>
#include <stdint.h>
#include <vector>
#include <limits>

namespace primecount {

/// Initialize a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
void init_moebius(std::vector<int32_t>& mu, int64_t max)
{
  mu.resize(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }
  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }
}

/// Initialize a vector with the least prime
/// factors of the integers <= max.
///
void init_least_factor(std::vector<int32_t>& lpf, int64_t max)
{
  lpf.resize(max + 1, 1);

  // phi(x / 1, c) contributes to the sum,
  // lpf[1] = MAX in order to pass
  // if (least_factor[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = std::numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;
}

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3)) operations, O(x^(1/3)) space.
///
int64_t pi_lmo_simple(int64_t x, int threads)
{
  int64_t x13 = iroot<3>(x);
  int64_t a = pi_meissel(x13);
  int64_t c = 7;

  // generate the primes <= x^(1/3)
  std::vector<int32_t> primes;
  primes.push_back(0);
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  if (a < c + 1 || isqrt(x) < primes[c + 1])
    return pi_meissel(x);

  std::vector<int32_t> moebius;
  std::vector<int32_t> least_factor;
  init_moebius(moebius, x13);
  init_least_factor(least_factor, x13);

  int64_t S1 = 0;
  int64_t S2 = 0;

  for (int64_t n = 1; n <= x13; n++)
    if (least_factor[n] > primes[c])
      S1 += moebius[n] * phi(x / n, c);

  for (int64_t b = c; b + 1 < a; b++)
    for (int64_t m = (x13 / primes[b + 1]) + 1; m <= x13; m++)
      if (least_factor[m] > primes[b + 1])
        S2 -= moebius[m] * phi(x / (m * primes[b + 1]), b);

  int64_t phi = S1 + S2;
  int64_t sum = phi + a - 1 - P2(x, a);

  return sum;
}

} // namespace primecount
<commit_msg>Simplified the algorithm<commit_after>///
/// @file  pi_lmo_simple.cpp
/// @brief Simple demonstration implementation of the
///        Lagarias-Miller-Odlyzko prime counting algorithm.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "imath.h"
#include "Pk.h"
#include "phi.h"

#include <primesieve/soe/PrimeSieve.h>
#include <primecount.h>
#include <stdint.h>
#include <vector>
#include <limits>

namespace primecount {

/// Initialize a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
void init_moebius(std::vector<int32_t>& mu, int64_t max)
{
  mu.resize(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }
  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }
}

/// Initialize a vector with the least prime
/// factors of the integers <= max.
///
void init_least_factor(std::vector<int32_t>& lpf, int64_t max)
{
  lpf.resize(max + 1, 1);

  // phi(x / 1, c) contributes to the sum,
  // lpf[1] = MAX in order to pass
  // if (least_factor[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = std::numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;
}

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3)) operations, O(x^(1/3)) space.
///
int64_t pi_lmo_simple(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  int64_t x13 = iroot<3>(x);
  int64_t a = pi_meissel(x13);

  // generate the primes <= x^(1/3)
  std::vector<int32_t> primes;
  primes.push_back(0);
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  std::vector<int32_t> moebius;
  std::vector<int32_t> least_factor;
  init_moebius(moebius, x13);
  init_least_factor(least_factor, x13);

  int64_t c = (a < 7) ? a : 7;
  int64_t S1 = 0;
  int64_t S2 = 0;

  for (int64_t n = 1; n <= x13; n++)
    if (least_factor[n] > primes[c])
      S1 += moebius[n] * phi(x / n, c);

  for (int64_t b = c; b + 1 < a; b++)
    for (int64_t m = (x13 / primes[b + 1]) + 1; m <= x13; m++)
      if (least_factor[m] > primes[b + 1])
        S2 -= moebius[m] * phi(x / (m * primes[b + 1]), b);

  int64_t phi = S1 + S2;
  int64_t sum = phi + a - 1 - P2(x, a);

  return sum;
}

} // namespace primecount
<|endoftext|>


<commit_before>///
/// @file  pi_lmo_simple.cpp
/// @brief Simple demonstration implementation of the
///        Lagarias-Miller-Odlyzko prime counting algorithm.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "imath.h"
#include "Pk.h"
#include "phi.h"

#include <primesieve/soe/PrimeSieve.h>
#include <primecount.h>
#include <stdint.h>
#include <vector>
#include <limits>

namespace primecount {

/// Initialize a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
void init_moebius(std::vector<int32_t>& mu, int64_t max)
{
  mu.resize(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }
  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }
}

/// Initialize a vector with the least prime
/// factors of the integers <= max.
///
void init_least_factor(std::vector<int32_t>& lpf, int64_t max)
{
  lpf.resize(max + 1, 1);

  // phi(x / 1, c) contributes to the sum,
  // lpf[1] = MAX in order to pass
  // if (least_factor[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = std::numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;
}

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3)) operations, O(x^(1/3)) space.
///
int64_t pi_lmo_simple(int64_t x, int threads)
{
  int64_t x13 = iroot<3>(x);
	int64_t a = pi_meissel(x13);
  int64_t c = 7;

  // generate the primes <= x^(1/3)
  std::vector<int32_t> primes;
  primes.push_back(0);
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  if (a < c || isqrt(x) < primes[c + 1])
    return pi_meissel(x);

  std::vector<int32_t> moebius;
  std::vector<int32_t> least_factor;
  init_moebius(moebius, x13);
  init_least_factor(least_factor, x13);

  int64_t S1 = 0;
  int64_t S2 = 0;

  for (int64_t n = 1; n <= x13; n++)
    if (least_factor[n] > primes[c])
      S1 += moebius[n] * phi(x / n, c);

	for (int64_t b = c; b + 1 < a; b++)
		for (int64_t m = (x13 / primes[b + 1]) + 1; m <= x13; m++)
			if (least_factor[m] > primes[b + 1])
        S2 -= moebius[m] * phi(x / (m * primes[b + 1]), b);

  int64_t phi = S1 + S2;
	int64_t sum = phi + a - 1 - P2(x, a);

	return sum;
}

} // namespace primecount
<commit_msg>Formatting<commit_after>///
/// @file  pi_lmo_simple.cpp
/// @brief Simple demonstration implementation of the
///        Lagarias-Miller-Odlyzko prime counting algorithm.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "imath.h"
#include "Pk.h"
#include "phi.h"

#include <primesieve/soe/PrimeSieve.h>
#include <primecount.h>
#include <stdint.h>
#include <vector>
#include <limits>

namespace primecount {

/// Initialize a vector with Möbius function values.
/// This implementation is based on code by Rick Sladkey
/// posted here: http://mathoverflow.net/a/99545
///
void init_moebius(std::vector<int32_t>& mu, int64_t max)
{
  mu.resize(max + 1, 1);

  for (int32_t i = 2; i * i <= max; i++)
  {
    if (mu[i] == 1)
    {
      for (int32_t j = i; j <= max; j += i)
        mu[j] *= -i;
      for (int32_t j = i * i; j <= max; j += i * i)
        mu[j] = 0;
    }
  }
  for (int32_t i = 2; i <= max; i++)
  {
    if (mu[i] == i)
      mu[i] = 1;
    else if (mu[i] == -i)
      mu[i] = -1;
    else if (mu[i] < 0)
      mu[i] = 1;
    else if (mu[i] > 0)
      mu[i] = -1;
  }
}

/// Initialize a vector with the least prime
/// factors of the integers <= max.
///
void init_least_factor(std::vector<int32_t>& lpf, int64_t max)
{
  lpf.resize(max + 1, 1);

  // phi(x / 1, c) contributes to the sum,
  // lpf[1] = MAX in order to pass
  // if (least_factor[1] > primes[c])
  if (lpf.size() > 1)
    lpf[1] = std::numeric_limits<int32_t>::max();

  for (int32_t i = 2; i * i <= max; i++)
    if (lpf[i] == 1)
      for (int32_t j = i * 2; j <= max; j += i)
        if (lpf[j] == 1)
          lpf[j] = i;

  for (int32_t i = 2; i <= max; i++)
    if (lpf[i] == 1)
      lpf[i] = i;
}

/// Calculate the number of primes below x using the
/// Lagarias-Miller-Odlyzko algorithm.
/// Run time: O(x^(2/3)) operations, O(x^(1/3)) space.
///
int64_t pi_lmo_simple(int64_t x, int threads)
{
  int64_t x13 = iroot<3>(x);
  int64_t a = pi_meissel(x13);
  int64_t c = 7;

  // generate the primes <= x^(1/3)
  std::vector<int32_t> primes;
  primes.push_back(0);
  PrimeSieve ps;
  ps.generate_N_Primes(a, &primes);

  if (a < c || isqrt(x) < primes[c + 1])
    return pi_meissel(x);

  std::vector<int32_t> moebius;
  std::vector<int32_t> least_factor;
  init_moebius(moebius, x13);
  init_least_factor(least_factor, x13);

  int64_t S1 = 0;
  int64_t S2 = 0;

  for (int64_t n = 1; n <= x13; n++)
    if (least_factor[n] > primes[c])
      S1 += moebius[n] * phi(x / n, c);

  for (int64_t b = c; b + 1 < a; b++)
    for (int64_t m = (x13 / primes[b + 1]) + 1; m <= x13; m++)
      if (least_factor[m] > primes[b + 1])
        S2 -= moebius[m] * phi(x / (m * primes[b + 1]), b);

  int64_t phi = S1 + S2;
  int64_t sum = phi + a - 1 - P2(x, a);

  return sum;
}

} // namespace primecount
<|endoftext|>


<commit_before>// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Platform specific code for POSIX goes here. This is not a platform on its
// own but contains the parts which are the same across POSIX platforms Linux,
// Mac OS and FreeBSD.

#include <unistd.h>
#include <errno.h>
#include <time.h>

#include <sys/socket.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

#include "v8.h"

#include "platform.h"

namespace v8 { namespace internal {

// ----------------------------------------------------------------------------
// POSIX date/time support.
//

int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
  struct rusage usage;

  if (getrusage(RUSAGE_SELF, &usage) < 0) return -1;
  *secs = usage.ru_utime.tv_sec;
  *usecs = usage.ru_utime.tv_usec;
  return 0;
}

double OS::TimeCurrentMillis() {
  struct timeval tv;
  if (gettimeofday(&tv, NULL) < 0) return 0.0;
  return (static_cast<double>(tv.tv_sec) * 1000) +
         (static_cast<double>(tv.tv_usec) / 1000);
}

int64_t OS::Ticks() {
  // gettimeofday has microsecond resolution.
  struct timeval tv;
  if (gettimeofday(&tv, NULL) < 0)
    return 0;
  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
}

char* OS::LocalTimezone(double time) {
  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
  struct tm* t = localtime(&tv);
  return const_cast<char*>(t->tm_zone);
}

double OS::DaylightSavingsOffset(double time) {
  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
  struct tm* t = localtime(&tv);
  return t->tm_isdst > 0 ? 3600 * msPerSecond : 0;
}

double OS::LocalTimeOffset() {
  time_t tv = time(NULL);
  struct tm* t = localtime(&tv);
  // tm_gmtoff includes any daylight savings offset, so subtract it.
  return static_cast<double>(t->tm_gmtoff * msPerSecond -
                             (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
}

// ----------------------------------------------------------------------------
// POSIX socket support.
//

class POSIXSocket : public Socket {
 public:
  explicit POSIXSocket() {
    // Create the socket.
    socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  }
  explicit POSIXSocket(int socket): socket_(socket) { }
  virtual ~POSIXSocket() { Shutdown(); }

  // Server initialization.
  bool Bind(const int port);
  bool Listen(int backlog) const;
  Socket* Accept() const;

  // Client initialization.
  bool Connect(const char* host, const char* port);

  // Shutdown socket for both read and write.
  bool Shutdown();

  // Data Transimission
  int Send(const char* data, int len) const;
  int Receive(char* data, int len) const;

  bool SetReuseAddress(bool reuse_address);

  bool IsValid() const { return socket_ != -1; }

 private:
  int socket_;
};

bool POSIXSocket::Bind(const int port) {
  if (!IsValid())  {
    return false;
  }

  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  addr.sin_port = htons(port);
  int status = bind(socket_,
                    reinterpret_cast<struct sockaddr *>(&addr),
                    sizeof(addr));
  return status == 0;
}

bool POSIXSocket::Listen(int backlog) const {
  if (!IsValid()) {
    return false;
  }

  int status = listen(socket_, backlog);
  return status == 0;
}

Socket* POSIXSocket::Accept() const {
  if (!IsValid()) {
    return NULL;
  }

  int socket = accept(socket_, NULL, NULL);
  if (socket == -1) {
    return NULL;
  } else {
    return new POSIXSocket(socket);
  }
}

bool POSIXSocket::Connect(const char* host, const char* port) {
  if (!IsValid()) {
    return false;
  }

  // Lookup host and port.
  struct addrinfo *result = NULL;
  struct addrinfo hints;
  memset(&hints, 0, sizeof(addrinfo));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;
  int status = getaddrinfo(host, port, &hints, &result);
  if (status != 0) {
    return false;
  }

  // Connect.
  status = connect(socket_, result->ai_addr, result->ai_addrlen);
  freeaddrinfo(result);
  return status == 0;
}

bool POSIXSocket::Shutdown() {
  if (IsValid()) {
    // Shutdown socket for both read and write.
    int status = shutdown(socket_, SHUT_RDWR);
    close(socket_);
    socket_ = -1;
    return status == 0;
  }
  return true;
}

int POSIXSocket::Send(const char* data, int len) const {
  int status = send(socket_, data, len, 0);
  return status;
}

int POSIXSocket::Receive(char* data, int len) const {
  int status = recv(socket_, data, len, 0);
  return status;
}

bool POSIXSocket::SetReuseAddress(bool reuse_address) {
  int on = reuse_address ? 1 : 0;
  int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  return status == 0;
}

bool Socket::Setup() {
  // Nothing to do on POSIX.
  return true;
}

int Socket::LastError() {
  return errno;
}

uint16_t Socket::HToN(uint16_t value) {
  return htons(value);
}

uint16_t Socket::NToH(uint16_t value) {
  return ntohs(value);
}

uint32_t Socket::HToN(uint32_t value) {
  return htonl(value);
}

uint32_t Socket::NToH(uint32_t value) {
  return ntohl(value);
}

Socket* OS::CreateSocket() {
  return new POSIXSocket();
}

} }  // namespace v8::internal
<commit_msg>Set svn:eol-style for platform-posix.cc to native.<commit_after>// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Platform specific code for POSIX goes here. This is not a platform on its
// own but contains the parts which are the same across POSIX platforms Linux,
// Mac OS and FreeBSD.

#include <unistd.h>
#include <errno.h>
#include <time.h>

#include <sys/socket.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

#include "v8.h"

#include "platform.h"

namespace v8 { namespace internal {

// ----------------------------------------------------------------------------
// POSIX date/time support.
//

int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
  struct rusage usage;

  if (getrusage(RUSAGE_SELF, &usage) < 0) return -1;
  *secs = usage.ru_utime.tv_sec;
  *usecs = usage.ru_utime.tv_usec;
  return 0;
}

double OS::TimeCurrentMillis() {
  struct timeval tv;
  if (gettimeofday(&tv, NULL) < 0) return 0.0;
  return (static_cast<double>(tv.tv_sec) * 1000) +
         (static_cast<double>(tv.tv_usec) / 1000);
}

int64_t OS::Ticks() {
  // gettimeofday has microsecond resolution.
  struct timeval tv;
  if (gettimeofday(&tv, NULL) < 0)
    return 0;
  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
}

char* OS::LocalTimezone(double time) {
  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
  struct tm* t = localtime(&tv);
  return const_cast<char*>(t->tm_zone);
}

double OS::DaylightSavingsOffset(double time) {
  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
  struct tm* t = localtime(&tv);
  return t->tm_isdst > 0 ? 3600 * msPerSecond : 0;
}

double OS::LocalTimeOffset() {
  time_t tv = time(NULL);
  struct tm* t = localtime(&tv);
  // tm_gmtoff includes any daylight savings offset, so subtract it.
  return static_cast<double>(t->tm_gmtoff * msPerSecond -
                             (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
}

// ----------------------------------------------------------------------------
// POSIX socket support.
//

class POSIXSocket : public Socket {
 public:
  explicit POSIXSocket() {
    // Create the socket.
    socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  }
  explicit POSIXSocket(int socket): socket_(socket) { }
  virtual ~POSIXSocket() { Shutdown(); }

  // Server initialization.
  bool Bind(const int port);
  bool Listen(int backlog) const;
  Socket* Accept() const;

  // Client initialization.
  bool Connect(const char* host, const char* port);

  // Shutdown socket for both read and write.
  bool Shutdown();

  // Data Transimission
  int Send(const char* data, int len) const;
  int Receive(char* data, int len) const;

  bool SetReuseAddress(bool reuse_address);

  bool IsValid() const { return socket_ != -1; }

 private:
  int socket_;
};

bool POSIXSocket::Bind(const int port) {
  if (!IsValid())  {
    return false;
  }

  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  addr.sin_port = htons(port);
  int status = bind(socket_,
                    reinterpret_cast<struct sockaddr *>(&addr),
                    sizeof(addr));
  return status == 0;
}

bool POSIXSocket::Listen(int backlog) const {
  if (!IsValid()) {
    return false;
  }

  int status = listen(socket_, backlog);
  return status == 0;
}

Socket* POSIXSocket::Accept() const {
  if (!IsValid()) {
    return NULL;
  }

  int socket = accept(socket_, NULL, NULL);
  if (socket == -1) {
    return NULL;
  } else {
    return new POSIXSocket(socket);
  }
}

bool POSIXSocket::Connect(const char* host, const char* port) {
  if (!IsValid()) {
    return false;
  }

  // Lookup host and port.
  struct addrinfo *result = NULL;
  struct addrinfo hints;
  memset(&hints, 0, sizeof(addrinfo));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;
  int status = getaddrinfo(host, port, &hints, &result);
  if (status != 0) {
    return false;
  }

  // Connect.
  status = connect(socket_, result->ai_addr, result->ai_addrlen);
  freeaddrinfo(result);
  return status == 0;
}

bool POSIXSocket::Shutdown() {
  if (IsValid()) {
    // Shutdown socket for both read and write.
    int status = shutdown(socket_, SHUT_RDWR);
    close(socket_);
    socket_ = -1;
    return status == 0;
  }
  return true;
}

int POSIXSocket::Send(const char* data, int len) const {
  int status = send(socket_, data, len, 0);
  return status;
}

int POSIXSocket::Receive(char* data, int len) const {
  int status = recv(socket_, data, len, 0);
  return status;
}

bool POSIXSocket::SetReuseAddress(bool reuse_address) {
  int on = reuse_address ? 1 : 0;
  int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  return status == 0;
}

bool Socket::Setup() {
  // Nothing to do on POSIX.
  return true;
}

int Socket::LastError() {
  return errno;
}

uint16_t Socket::HToN(uint16_t value) {
  return htons(value);
}

uint16_t Socket::NToH(uint16_t value) {
  return ntohs(value);
}

uint32_t Socket::HToN(uint32_t value) {
  return htonl(value);
}

uint32_t Socket::NToH(uint32_t value) {
  return ntohl(value);
}

Socket* OS::CreateSocket() {
  return new POSIXSocket();
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before><commit_msg>Reverting the whitespaces too<commit_after><|endoftext|>


<commit_before>// Author: Mingcheng Chen (linyufly@gmail.com)

#include "math.h"

#include "sparse_matrix.h"

#include <cstdio>

#include <vector>

void conjugate_gradient_test() {
  printf("conjugate_gradient_test {\n");

  SparseMatrix a(4, 2);
  a.set_element(0, 0, 1.0);
  a.set_element(0, 1, 2.0);

  a.set_element(1, 0, 2.0);
  a.set_element(1, 1, -3.0);

  a.set_element(2, 0, 4.0);
  a.set_element(2, 1, -1.0);

  a.set_element(3, 0, -5.0);
  a.set_element(3, 1, 2.0);

  // Suppose solution is (2, 3).
  std::vector<double> b(4);
  b[0] = 3.0;  // 8.0
  b[1] = 2.0;  // -5.0
  b[2] = -4.0;
  b[3] = 5.0;

  std::vector<double> x(2);
  x[0] = x[1] = 0.0;

  Math::conjugate_gradient(a, &b[0], 2, &x[0]);

  std::vector<double> c(4);
  a.multiply_column(&x[0], &c[0]);

  printf("x: %lf %lf\n", x[0], x[1]);

  for (int i = 0; i < 4; i++) {
    printf(" %lf(%lf)", c[i], b[i]);
  }
  printf("\n");

  printf("} conjugate_gradient_test\n");
}

int main() {
  conjugate_gradient_test();

  return 0;
}

<commit_msg>Added a test<commit_after>// Author: Mingcheng Chen (linyufly@gmail.com)

#include "math.h"

#include "sparse_matrix.h"

#include <cstdio>

#include <vector>

void conjugate_gradient_test() {
  printf("conjugate_gradient_test {\n");

  // Test Case 1
  SparseMatrix a(4, 2);
  a.set_element(0, 0, 1.0);
  a.set_element(0, 1, 2.0);

  a.set_element(1, 0, 2.0);
  a.set_element(1, 1, -3.0);

  a.set_element(2, 0, 4.0);
  a.set_element(2, 1, -1.0);

  a.set_element(3, 0, -5.0);
  a.set_element(3, 1, 2.0);

  // Suppose solution is (2, 3).
  std::vector<double> b(4);
  b[0] = 3.0;  // 8.0
  b[1] = 2.0;  // -5.0
  b[2] = -4.0;
  b[3] = 5.0;

  std::vector<double> x(2);
  x[0] = x[1] = 0.0;

  Math::conjugate_gradient(a, &b[0], 2, &x[0]);

  std::vector<double> c(4);
  a.multiply_column(&x[0], &c[0]);

  printf("x: %lf %lf\n", x[0], x[1]);

  for (int i = 0; i < 4; i++) {
    printf(" %lf(%lf)", c[i], b[i]);
  }
  printf("\n");

  // Test Case 2
  a = SparseMatrix(1, 2);
  a.set_element(0, 0, 1.0);
  a.set_element(0, 1, 2.0);

  b.resize(1);
  b[0] = 3.0;

  x[0] = x[1] = 0.0;

  Math::conjugate_gradient(a, &b[0], 1, &x[0]);

  c.resize(1);
  a.multiply_column(&x[0], &c[0]);

  printf("x: %lf %lf\n", x[0], x[1]);

  for (int i = 0; i < 1; i++) {
    printf(" %lf(%lf)", c[i], b[i]);
  }
  printf("\n");

  printf("} conjugate_gradient_test\n");
}

int main() {
  conjugate_gradient_test();

  return 0;
}

<|endoftext|>


<commit_before>//-----------------------------------
// Copyright Pierric Gimmig 2013-2017
//-----------------------------------

#include "orbittreeview.h"

#include <QFontDatabase>
#include <QHeaderView>
#include <QKeyEvent>
#include <QMenu>
#include <QPainter>
#include <QScrollBar>
#include <QSignalMapper>
#include <set>

#include "../OrbitGl/App.h"
#include "../OrbitGl/DataView.h"
#include "orbitglwidget.h"

//-----------------------------------------------------------------------------
OrbitTreeView::OrbitTreeView(QWidget* parent)
    : QTreeView(parent),
      m_Model(nullptr),
      m_Timer(nullptr),
      m_AutoResize(true) {
  header()->setSortIndicatorShown(true);
  header()->setSectionsClickable(true);

  setRootIsDecorated(false);
  setItemsExpandable(false);
  setContextMenuPolicy(Qt::CustomContextMenu);
  setSelectionBehavior(QTreeView::SelectRows);
  setUniformRowHeights(true);
  setTextElideMode(Qt::ElideMiddle);

  connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this,
          SLOT(OnSort(int, Qt::SortOrder)));

  connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this,
          SLOT(ShowContextMenu(const QPoint&)));

  connect(header(), SIGNAL(sectionResized(int, int, int)), this,
          SLOT(columnResized(int, int, int)));

  connect(this, SIGNAL(clicked(const QModelIndex)), this,
          SLOT(OnClicked(const QModelIndex)));

  connect(this->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), this,
          SLOT(OnRangeChanged(int, int)));
}

//-----------------------------------------------------------------------------
OrbitTreeView::~OrbitTreeView() {
  delete m_Model;
  delete m_Timer;
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Initialize(DataViewType a_Type) {
  m_Model = new OrbitTableModel(a_Type);
  setModel(m_Model);
  header()->resizeSections(QHeaderView::ResizeToContents);

  if (m_Model->GetUpdatePeriodMs() > 0) {
    m_Timer = new QTimer(this);
    connect(m_Timer, SIGNAL(timeout()), this, SLOT(OnTimer()));
    m_Timer->start(m_Model->GetUpdatePeriodMs());
  }

  if (a_Type == DataViewType::FUNCTIONS ||
      a_Type == DataViewType::LIVEFUNCTIONS ||
      a_Type == DataViewType::CALLSTACK || a_Type == DataViewType::MODULES ||
      a_Type == DataViewType::GLOBALS) {
    setSelectionMode(ExtendedSelection);
  }

  if (a_Type == DataViewType::LOG) {
    const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
    this->setFont(fixedFont);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::SetDataModel(std::shared_ptr<DataView> a_Model) {
  m_Model = new OrbitTableModel();
  m_Model->SetDataView(a_Model);
  setModel(m_Model);
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnSort(int a_Section, Qt::SortOrder a_Order) {
  m_Model->sort(a_Section, a_Order);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnFilter(const QString& a_Filter) {
  m_Model->OnFilter(a_Filter);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Select(int a_Row) {
  QModelIndex idx = m_Model->CreateIndex(a_Row, 0);
  m_Model->OnClicked(idx);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnTimer() {
  if (this->isVisible() && !m_Model->GetDataView()->SkipTimer()) {
    m_Model->OnTimer();
    Refresh();
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnClicked(const QModelIndex& index) {
  m_Model->OnClicked(index);

  for (OrbitTreeView* treeView : m_Links) {
    treeView->Refresh();
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Refresh() {
  QModelIndexList list = selectionModel()->selectedIndexes();

  if (this->m_Model->GetDataView()->GetType() == DataViewType::LIVEFUNCTIONS) {
    m_Model->layoutAboutToBeChanged();
    m_Model->layoutChanged();
    return;
  }

  reset();

  // Re-select previous selection
  int selected = m_Model->GetSelectedIndex();
  if (selected >= 0) {
    QItemSelectionModel* selection = selectionModel();
    QModelIndex idx = m_Model->CreateIndex(selected, 0);
    selection->select(
        idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::resizeEvent(QResizeEvent* event) {
  if (m_AutoResize && m_Model && m_Model->GetDataView()) {
    QSize headerSize = size();
    const std::vector<float>& columnRatios =
        m_Model->GetDataView()->GetColumnHeadersRatios();
    for (size_t i = 0; i < columnRatios.size(); ++i) {
      float ratio = columnRatios[i];
      if (ratio > 0.f) {
        header()->resizeSection(i,
                                static_cast<int>(headerSize.width() * ratio));
      }
    }
  }

  QTreeView::resizeEvent(event);
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Link(OrbitTreeView* a_Link) {
  m_Links.push_back(a_Link);

  std::shared_ptr<DataView> dataView = a_Link->GetModel()->GetDataView();
  m_Model->GetDataView()->LinkDataView(dataView.get());
}

//-----------------------------------------------------------------------------
void OrbitTreeView::SetGlWidget(OrbitGLWidget* a_GlWidget) {
  this->m_Model->GetDataView()->SetGlPanel(a_GlWidget->GetPanel());
}

//-----------------------------------------------------------------------------
void OrbitTreeView::drawRow(QPainter* painter,
                            const QStyleOptionViewItem& options,
                            const QModelIndex& index) const {
  QTreeView::drawRow(painter, options, index);
}

//-----------------------------------------------------------------------------
QMenu* GContextMenu;

//-----------------------------------------------------------------------------
void OrbitTreeView::ShowContextMenu(const QPoint& pos) {
  QModelIndex index = this->indexAt(pos);
  if (index.isValid()) {
    std::vector<std::wstring> menu =
        m_Model->GetDataView()->GetContextMenu(index.row());

    if (menu.size() > 0) {
      QMenu contextMenu(tr("ContextMenu"), this);
      GContextMenu = &contextMenu;
      QSignalMapper signalMapper(this);
      std::vector<QAction*> actions;

      for (int i = 0; i < (int)menu.size(); ++i) {
        actions.push_back(new QAction(QString::fromStdWString(menu[i])));
        connect(actions[i], SIGNAL(triggered()), &signalMapper, SLOT(map()));
        signalMapper.setMapping(actions[i], i);
        contextMenu.addAction(actions[i]);
      }

      connect(&signalMapper, SIGNAL(mapped(int)), this,
              SLOT(OnMenuClicked(int)));
      contextMenu.exec(mapToGlobal(pos));
      GContextMenu = nullptr;

      for (QAction* action : actions) delete action;
    }
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnMenuClicked(int a_Index) {
  QModelIndexList list = selectionModel()->selectedIndexes();
  std::set<int> selection;
  for (QModelIndex& index : list) {
    selection.insert(index.row());
  }

  std::vector<int> indices(selection.begin(), selection.end());
  if (indices.size()) {
    const std::vector<std::wstring>& menu =
        m_Model->GetDataView()->GetContextMenu(indices[0]);
    m_Model->GetDataView()->OnContextMenu(menu[a_Index], a_Index, indices);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::keyPressEvent(QKeyEvent* event) {
  if (event->matches(QKeySequence::Copy)) {
    QModelIndexList list = selectionModel()->selectedIndexes();
    std::set<int> selection;
    for (QModelIndex& index : list) {
      selection.insert(index.row());
    }

    std::vector<int> items(selection.begin(), selection.end());
    this->m_Model->GetDataView()->CopySelection(items);
  } else {
    QTreeView::keyPressEvent(event);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnRangeChanged(int /*a_Min*/, int a_Max) {
  std::shared_ptr<DataView> DataView = m_Model->GetDataView();
  if (DataView->ScrollToBottom()) {
    verticalScrollBar()->setValue(a_Max);
  }
}

//-----------------------------------------------------------------------------
std::wstring OrbitTreeView::GetLabel() {
  if (m_Model && m_Model->GetDataView()) {
    return m_Model->GetDataView()->GetLabel();
  }

  return L"";
}

//-----------------------------------------------------------------------------
void OrbitTreeView::columnResized(int /*column*/, int /*oldSize*/,
                                  int /*newSize*/) {
#ifdef _WIN32
  if ((GetKeyState(VK_LBUTTON) & 0x100) != 0) {
    m_AutoResize = false;
  }
#endif
}
<commit_msg>Allow user to resize columns after initial width is set in treeview.<commit_after>//-----------------------------------
// Copyright Pierric Gimmig 2013-2017
//-----------------------------------

#include "orbittreeview.h"

#include <QFontDatabase>
#include <QHeaderView>
#include <QKeyEvent>
#include <QMenu>
#include <QPainter>
#include <QScrollBar>
#include <QSignalMapper>
#include <set>

#include "../OrbitGl/App.h"
#include "../OrbitGl/DataView.h"
#include "orbitglwidget.h"

//-----------------------------------------------------------------------------
OrbitTreeView::OrbitTreeView(QWidget* parent)
    : QTreeView(parent),
      m_Model(nullptr),
      m_Timer(nullptr),
      m_AutoResize(true) {
  header()->setSortIndicatorShown(true);
  header()->setSectionsClickable(true);

  setRootIsDecorated(false);
  setItemsExpandable(false);
  setContextMenuPolicy(Qt::CustomContextMenu);
  setSelectionBehavior(QTreeView::SelectRows);
  setUniformRowHeights(true);
  setTextElideMode(Qt::ElideMiddle);

  connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this,
          SLOT(OnSort(int, Qt::SortOrder)));

  connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this,
          SLOT(ShowContextMenu(const QPoint&)));

  connect(header(), SIGNAL(sectionResized(int, int, int)), this,
          SLOT(columnResized(int, int, int)));

  connect(this, SIGNAL(clicked(const QModelIndex)), this,
          SLOT(OnClicked(const QModelIndex)));

  connect(this->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), this,
          SLOT(OnRangeChanged(int, int)));
}

//-----------------------------------------------------------------------------
OrbitTreeView::~OrbitTreeView() {
  delete m_Model;
  delete m_Timer;
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Initialize(DataViewType a_Type) {
  m_Model = new OrbitTableModel(a_Type);
  setModel(m_Model);
  header()->resizeSections(QHeaderView::ResizeToContents);

  if (m_Model->GetUpdatePeriodMs() > 0) {
    m_Timer = new QTimer(this);
    connect(m_Timer, SIGNAL(timeout()), this, SLOT(OnTimer()));
    m_Timer->start(m_Model->GetUpdatePeriodMs());
  }

  if (a_Type == DataViewType::FUNCTIONS ||
      a_Type == DataViewType::LIVEFUNCTIONS ||
      a_Type == DataViewType::CALLSTACK || a_Type == DataViewType::MODULES ||
      a_Type == DataViewType::GLOBALS) {
    setSelectionMode(ExtendedSelection);
  }

  if (a_Type == DataViewType::LOG) {
    const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
    this->setFont(fixedFont);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::SetDataModel(std::shared_ptr<DataView> a_Model) {
  m_Model = new OrbitTableModel();
  m_Model->SetDataView(a_Model);
  setModel(m_Model);
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnSort(int a_Section, Qt::SortOrder a_Order) {
  m_Model->sort(a_Section, a_Order);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnFilter(const QString& a_Filter) {
  m_Model->OnFilter(a_Filter);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Select(int a_Row) {
  QModelIndex idx = m_Model->CreateIndex(a_Row, 0);
  m_Model->OnClicked(idx);
  Refresh();
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnTimer() {
  if (this->isVisible() && !m_Model->GetDataView()->SkipTimer()) {
    m_Model->OnTimer();
    Refresh();
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnClicked(const QModelIndex& index) {
  m_Model->OnClicked(index);

  for (OrbitTreeView* treeView : m_Links) {
    treeView->Refresh();
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Refresh() {
  QModelIndexList list = selectionModel()->selectedIndexes();

  if (this->m_Model->GetDataView()->GetType() == DataViewType::LIVEFUNCTIONS) {
    m_Model->layoutAboutToBeChanged();
    m_Model->layoutChanged();
    return;
  }

  reset();

  // Re-select previous selection
  int selected = m_Model->GetSelectedIndex();
  if (selected >= 0) {
    QItemSelectionModel* selection = selectionModel();
    QModelIndex idx = m_Model->CreateIndex(selected, 0);
    selection->select(
        idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::resizeEvent(QResizeEvent* event) {
  if (m_AutoResize && m_Model && m_Model->GetDataView()) {
    QSize headerSize = size();
    const std::vector<float>& columnRatios =
        m_Model->GetDataView()->GetColumnHeadersRatios();
    for (size_t i = 0; i < columnRatios.size(); ++i) {
      float ratio = columnRatios[i];
      if (ratio > 0.f) {
        header()->resizeSection(i,
                                static_cast<int>(headerSize.width() * ratio));
      }
    }
  }

  // Apply initial column ratio only on first resize to allow user to resize
  // columns manually.
  m_AutoResize = false;

  QTreeView::resizeEvent(event);
}

//-----------------------------------------------------------------------------
void OrbitTreeView::Link(OrbitTreeView* a_Link) {
  m_Links.push_back(a_Link);

  std::shared_ptr<DataView> dataView = a_Link->GetModel()->GetDataView();
  m_Model->GetDataView()->LinkDataView(dataView.get());
}

//-----------------------------------------------------------------------------
void OrbitTreeView::SetGlWidget(OrbitGLWidget* a_GlWidget) {
  this->m_Model->GetDataView()->SetGlPanel(a_GlWidget->GetPanel());
}

//-----------------------------------------------------------------------------
void OrbitTreeView::drawRow(QPainter* painter,
                            const QStyleOptionViewItem& options,
                            const QModelIndex& index) const {
  QTreeView::drawRow(painter, options, index);
}

//-----------------------------------------------------------------------------
QMenu* GContextMenu;

//-----------------------------------------------------------------------------
void OrbitTreeView::ShowContextMenu(const QPoint& pos) {
  QModelIndex index = this->indexAt(pos);
  if (index.isValid()) {
    std::vector<std::wstring> menu =
        m_Model->GetDataView()->GetContextMenu(index.row());

    if (menu.size() > 0) {
      QMenu contextMenu(tr("ContextMenu"), this);
      GContextMenu = &contextMenu;
      QSignalMapper signalMapper(this);
      std::vector<QAction*> actions;

      for (int i = 0; i < (int)menu.size(); ++i) {
        actions.push_back(new QAction(QString::fromStdWString(menu[i])));
        connect(actions[i], SIGNAL(triggered()), &signalMapper, SLOT(map()));
        signalMapper.setMapping(actions[i], i);
        contextMenu.addAction(actions[i]);
      }

      connect(&signalMapper, SIGNAL(mapped(int)), this,
              SLOT(OnMenuClicked(int)));
      contextMenu.exec(mapToGlobal(pos));
      GContextMenu = nullptr;

      for (QAction* action : actions) delete action;
    }
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnMenuClicked(int a_Index) {
  QModelIndexList list = selectionModel()->selectedIndexes();
  std::set<int> selection;
  for (QModelIndex& index : list) {
    selection.insert(index.row());
  }

  std::vector<int> indices(selection.begin(), selection.end());
  if (indices.size()) {
    const std::vector<std::wstring>& menu =
        m_Model->GetDataView()->GetContextMenu(indices[0]);
    m_Model->GetDataView()->OnContextMenu(menu[a_Index], a_Index, indices);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::keyPressEvent(QKeyEvent* event) {
  if (event->matches(QKeySequence::Copy)) {
    QModelIndexList list = selectionModel()->selectedIndexes();
    std::set<int> selection;
    for (QModelIndex& index : list) {
      selection.insert(index.row());
    }

    std::vector<int> items(selection.begin(), selection.end());
    this->m_Model->GetDataView()->CopySelection(items);
  } else {
    QTreeView::keyPressEvent(event);
  }
}

//-----------------------------------------------------------------------------
void OrbitTreeView::OnRangeChanged(int /*a_Min*/, int a_Max) {
  std::shared_ptr<DataView> DataView = m_Model->GetDataView();
  if (DataView->ScrollToBottom()) {
    verticalScrollBar()->setValue(a_Max);
  }
}

//-----------------------------------------------------------------------------
std::wstring OrbitTreeView::GetLabel() {
  if (m_Model && m_Model->GetDataView()) {
    return m_Model->GetDataView()->GetLabel();
  }

  return L"";
}

//-----------------------------------------------------------------------------
void OrbitTreeView::columnResized(int /*column*/, int /*oldSize*/,
                                  int /*newSize*/) {
#ifdef _WIN32
  if ((GetKeyState(VK_LBUTTON) & 0x100) != 0) {
    m_AutoResize = false;
  }
#endif
}
<|endoftext|>


<commit_before>/*
T0 DA for online calibration

Contact: Alla.Maevskaya@cern.ch
Run Type: AMPLITUDE_CALIBRATION
DA Type: MON
Number of events needed: 5000
Input Files: inLaser.dat, external parameters
Output Files: daLaser.root, to be exported to the DAQ FXS
Trigger types used: CALIBRATION_EVENT

*/

#define FILE_OUT "daLaser.root"
#define FILE_IN "inLaser.dat"
#include <daqDA.h>
#include <event.h>
#include <monitor.h>

#include <Riostream.h>
#include <stdio.h>
#include <stdlib.h>

//AliRoot
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliT0RawReader.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include "TFile.h"
#include "TKey.h"
#include "TH2S.h"
#include "TObject.h"
#include "TBenchmark.h"
#include "TRandom.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TString.h"
#include "TH1.h"
#include "TF1.h"
#include "TSpectrum.h"
#include "TVirtualFitter.h"
//AMORE
//
#ifdef ALI_AMORE
#include <AmoreDA.h>
#endif

float lcfd, hcfd;
/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {
  int status;

  /* magic line */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  Int_t nEntries = daqDA_ECS_getTotalIteration(); // usually = 11 = Nb of calibration runs
 cout<<" nEntries "<<nEntries<<endl;
 Int_t nInit=1;  // = 0 all DAC values ; = 1 DAC=0 excluded (default=1)
  // Reading current iteration
  Int_t nIndex = daqDA_ECS_getCurrentIteration();
  if(nIndex<0 || nIndex>nEntries) {printf("\n Failed: nIndex = %d\n",nIndex); return -1 ;}

// decode the input line
  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  Float_t mipsin[20];
   if(daqDA_DB_getFile(FILE_IN, FILE_IN)){
     printf("Couldn't get input file >>inLaser.dat<< from DAQ_DB !!!\n");
     return -1;
  }

  ifstream filein(FILE_IN,ios::in);
  Int_t k=0;
  while (k<nEntries ) {
    filein >>mipsin[k] ;
    cout<<" "<<mipsin[k]<<endl;
    k++; }
  filein>>lcfd;
  filein>>hcfd;
  filein.close();

  /*
  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }
  */

  // Char_t inputFile[256]="";

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("T0 monitoring program started\n");

  // Allocation of histograms - start

  TH1F *hQTC[24];  TH1F *hLED[24]; TH1F *hCFD[24];
  printf(" CFD low limit %f high %f",lcfd, hcfd);

  for(Int_t ic=0; ic<24; ic++)
    {
      hQTC[ic] = new TH1F(Form("hQTC%d_%d",ic+1,nIndex),"QTC",1000, 500, 4500);
      hLED[ic] = new TH1F(Form("hLED%d_%d",ic+1,nIndex),"LED",300,300,600);
      hCFD[ic] = new TH1F(Form("hCFD%d_%d",ic+1,nIndex),"CFD", Int_t ((hcfd-lcfd)/2), lcfd, hcfd);
    }

  // Allocation of histograms - end

  // Reading current iteration

  Int_t iev=0;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==(int)MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    switch (event->eventType){

    case START_OF_RUN:
      break;

    case END_OF_RUN:
      break;

    case CALIBRATION_EVENT:
      //      case PHYSICS_EVENT:
      iev++;

      if(iev==1) printf("First event  %i\n",iev);

      // Initalize raw-data reading and decoding
      AliRawReader *reader = new AliRawReaderDate((void*)event);

      // Enable the following two lines in case of real-data
      reader->RequireHeader(kTRUE);
      AliT0RawReader *start = new AliT0RawReader(reader, kTRUE);

      // Read raw data
      Int_t allData[106][5];
      for(Int_t i0=0;i0<106;i0++)
      	for(Int_t j0=0;j0<5;j0++)
		allData[i0][j0] = 0;

      if(start->Next()){
        for (Int_t i=0; i<106; i++) {
	  for(Int_t iHit=0;iHit<5;iHit++){
	    allData[i][iHit]= start->GetData(i,iHit);
	  }
        }
      }
      else
	printf("No data for T0 found!!!\n");

      // Fill the histograms

      for (Int_t ik = 0; ik<24; ik+=2)
	{
	  Int_t cc = ik/2;
	  if(allData[ik+25][0]>0 && allData[ik+26][0]>0)
	    hQTC[cc]->Fill((allData[ik+25][0]-allData[ik+26][0]));
	  if(allData[cc+13][0]>0 && allData[cc+1][0]>0)
	    hLED[cc]->Fill(allData[cc+13][0]-allData[cc+1][0]);
	  if(allData[cc+1][0] > 0) hCFD[cc]->Fill(allData[cc+1][0]);
	  //	  printf("%i %i CFD %i LED_CFD %i\n",
	  //	  ik,cc,allData[cc+1][0],allData[cc+1][0]);

	}

      for (Int_t ik = 24; ik<48; ik+=2)
	{
	  Int_t cc = ik/2;
	   if(allData[ik+57][0]>0 && allData[ik+58][0]>0 && allData[cc+45][0]>0)
	     hQTC[cc]->Fill(allData[ik+57][0]-allData[ik+58][0]);

	   if(allData[cc+57][0]>0 && allData[cc+45][0]>0)
	     hLED[cc]->Fill(allData[cc+57][0]-allData[cc+45][0]);
	   if(allData[cc+45][0] > 0) hCFD[cc]->Fill(allData[cc+45][0]);
	   //  printf("%i %i CFD %i LED_CFD %i\n",
	   //  ik,cc,allData[cc+45][0],allData[cc+45][0]);

	}

      delete start;
      start = 0x0;
      delete reader;
      reader= 0x0;
      // End of fill histograms

    }

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      printf("Number of events processed - %i\n ",iev);
      break;
    }
  }

  printf("After loop, before writing histos\n");
  TH1F* hAmp = new TH1F("hAmpLaser"," Laser amplitude ", 1000, 0.5, 20.5);
  for(Int_t k=0; k<nEntries; k++)   hAmp->Fill(mipsin[k]);
  // write a file with the histograms
  TFile *hist=0;
  if(nIndex == 1 )
    hist = new TFile(FILE_OUT,"RECREATE");
  else
    hist = new TFile(FILE_OUT,"UPDATE");
  hist->cd();

  for(Int_t j=0;j<24;j++)
    {
      if(hQTC[j]->GetEntries()>0) hQTC[j]->Write();
      if(hLED[j]->GetEntries()>0) hLED[j]->Write();
      if(hCFD[j]->GetEntries()>0) hCFD[j]->Write();
    }
  hAmp->Write();

  hist->Close();
  delete hist;

  status=0;

  /* export file to FXS */
  if (daqDA_FES_storeFile(FILE_OUT, "AMPLITUDE_CALIBRATION")) {
    status=-2;
  }

  return status;
}

<commit_msg>Warning fixed, thanks  Cvetan<commit_after>/*
T0 DA for online calibration

Contact: Alla.Maevskaya@cern.ch
Run Type: AMPLITUDE_CALIBRATION
DA Type: MON
Number of events needed: 5000
Input Files: inLaser.dat, external parameters
Output Files: daLaser.root, to be exported to the DAQ FXS
Trigger types used: CALIBRATION_EVENT

*/

#define FILE_OUT "daLaser.root"
#define FILE_IN "inLaser.dat"
#include <daqDA.h>
#include <event.h>
#include <monitor.h>

#include <Riostream.h>
#include <stdio.h>
#include <stdlib.h>

//AliRoot
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliT0RawReader.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include "TFile.h"
#include "TKey.h"
#include "TH2S.h"
#include "TObject.h"
#include "TBenchmark.h"
#include "TRandom.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TString.h"
#include "TH1.h"
#include "TF1.h"
#include "TSpectrum.h"
#include "TVirtualFitter.h"
//AMORE
//
#ifdef ALI_AMORE
#include <AmoreDA.h>
#endif

float lcfd, hcfd;
/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {
  int status;

  /* magic line */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  Int_t nEntries = daqDA_ECS_getTotalIteration(); // usually = 11 = Nb of calibration runs
 cout<<" nEntries "<<nEntries<<endl;
 Int_t nInit=1;  // = 0 all DAC values ; = 1 DAC=0 excluded (default=1)
  // Reading current iteration
  Int_t nIndex = daqDA_ECS_getCurrentIteration();
  if(nIndex<0 || nIndex>nEntries) {printf("\n Failed: nIndex = %d\n",nIndex); return -1 ;}

// decode the input line
  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  Float_t mipsin[20];
   if(daqDA_DB_getFile(FILE_IN, FILE_IN)){
     printf("Couldn't get input file >>inLaser.dat<< from DAQ_DB !!!\n");
     return -1;
  }

  ifstream filein(FILE_IN,ios::in);
  Int_t k=0;
  while (k<nEntries ) {
    filein >>mipsin[k] ;
    cout<<" "<<mipsin[k]<<endl;
    k++; }
  filein>>lcfd;
  filein>>hcfd;
  filein.close();

  /*
  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }
  */

  // Char_t inputFile[256]="";

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("T0 monitoring program started\n");

  // Allocation of histograms - start

  TH1F *hQTC[24];  TH1F *hLED[24]; TH1F *hCFD[24];
  printf(" CFD low limit %f high %f",lcfd, hcfd);

  for(Int_t ic=0; ic<24; ic++)
    {
      hQTC[ic] = new TH1F(Form("hQTC%d_%d",ic+1,nIndex),"QTC",1000, 500, 4500);
      hLED[ic] = new TH1F(Form("hLED%d_%d",ic+1,nIndex),"LED",300,300,600);
      hCFD[ic] = new TH1F(Form("hCFD%d_%d",ic+1,nIndex),"CFD", Int_t ((hcfd-lcfd)/2), lcfd, hcfd);
    }

  // Allocation of histograms - end

  // Reading current iteration

  Int_t iev=0;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==(int)MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    switch (event->eventType){

    case START_OF_RUN:
      break;

    case END_OF_RUN:
      break;

    case CALIBRATION_EVENT:
      //      case PHYSICS_EVENT:
      iev++;

      if(iev==1) printf("First event  %i\n",iev);

      // Initalize raw-data reading and decoding
      AliRawReader *reader = new AliRawReaderDate((void*)event);

      // Enable the following two lines in case of real-data
      reader->RequireHeader(kTRUE);
      AliT0RawReader *start = new AliT0RawReader(reader, kTRUE);

      // Read raw data
      Int_t allData[106][5];
      for(Int_t i0=0;i0<106;i0++)
      	for(Int_t j0=0;j0<5;j0++)
		allData[i0][j0] = 0;

      if(start->Next()){
        for (Int_t i=0; i<106; i++) {
	  for(Int_t iHit=0;iHit<5;iHit++){
	    allData[i][iHit]= start->GetData(i,iHit);
	  }
        }
      }
      else
	printf("No data for T0 found!!!\n");

      // Fill the histograms

      for (Int_t ik = 0; ik<24; ik+=2)
	{
	  Int_t cc = ik/2;
	  if(allData[ik+25][0]>0 && allData[ik+26][0]>0)
	    hQTC[cc]->Fill((allData[ik+25][0]-allData[ik+26][0]));
	  if(allData[cc+13][0]>0 && allData[cc+1][0]>0)
	    hLED[cc]->Fill(allData[cc+13][0]-allData[cc+1][0]);
	  if(allData[cc+1][0] > 0) hCFD[cc]->Fill(allData[cc+1][0]);
	  //	  printf("%i %i CFD %i LED_CFD %i\n",
	  //	  ik,cc,allData[cc+1][0],allData[cc+1][0]);

	}

      for (Int_t ik = 24; ik<48; ik+=2)
	{
	  Int_t cc = ik/2;
	   if(allData[ik+57][0]>0 && allData[ik+58][0]>0 && allData[cc+45][0]>0)
	     hQTC[cc]->Fill(allData[ik+57][0]-allData[ik+58][0]);

	   if(allData[cc+57][0]>0 && allData[cc+45][0]>0)
	     hLED[cc]->Fill(allData[cc+57][0]-allData[cc+45][0]);
	   if(allData[cc+45][0] > 0) hCFD[cc]->Fill(allData[cc+45][0]);
	   //  printf("%i %i CFD %i LED_CFD %i\n",
	   //  ik,cc,allData[cc+45][0],allData[cc+45][0]);

	}

      delete start;
      start = 0x0;
      delete reader;
      reader= 0x0;
      // End of fill histograms

    }

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      printf("Number of events processed - %i\n ",iev);
      break;
    }
  }

  printf("After loop, before writing histos\n");
  TH1F* hAmp = new TH1F("hAmpLaser"," Laser amplitude ", 1000, 0.5, 20.5);
  for(Int_t i=0; i<nEntries; i++)   hAmp->Fill(mipsin[i]);
  // write a file with the histograms
  TFile *hist=0;
  if(nIndex == 1 )
    hist = new TFile(FILE_OUT,"RECREATE");
  else
    hist = new TFile(FILE_OUT,"UPDATE");
  hist->cd();

  for(Int_t j=0;j<24;j++)
    {
      if(hQTC[j]->GetEntries()>0) hQTC[j]->Write();
      if(hLED[j]->GetEntries()>0) hLED[j]->Write();
      if(hCFD[j]->GetEntries()>0) hCFD[j]->Write();
    }
  hAmp->Write();

  hist->Close();
  delete hist;

  status=0;

  /* export file to FXS */
  if (daqDA_FES_storeFile(FILE_OUT, "AMPLITUDE_CALIBRATION")) {
    status=-2;
  }

  return status;
}

<|endoftext|>


<commit_before>#ifndef UNIT_TEST // disable program main loop while unit testing in progress

#include <Arduino.h>
#include "calculator.h"

Calculator calc;

void blink_once(unsigned int delay_ms)
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(delay_ms);
    digitalWrite(LED_BUILTIN, LOW);
    delay(delay_ms);
}

void setup() {
    Serial.begin(9600);
    Serial.println("Program started!");
}

void loop() {
    Serial.print("Addition: ");
    Serial.println(calc.add(25, 17));
    blink_once(200);
    Serial.print("Subtraction: ");
    Serial.println(calc.sub(10, 3));
    blink_once(200);
    Serial.print("Multiplication: ");
    Serial.println(calc.mul(3, 3));
    blink_once(200);
    Serial.print("Division: ");
    Serial.println(calc.div(100, 3));
    blink_once(200);
}

#endif
<commit_msg>Added pinMode (#23)<commit_after>#ifndef UNIT_TEST // disable program main loop while unit testing in progress

#include <Arduino.h>
#include "calculator.h"

Calculator calc;

void blink_once(unsigned int delay_ms)
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(delay_ms);
    digitalWrite(LED_BUILTIN, LOW);
    delay(delay_ms);
}

void setup() {
    Serial.begin(9600);
    Serial.println("Program started!");
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    Serial.print("Addition: ");
    Serial.println(calc.add(25, 17));
    blink_once(200);
    Serial.print("Subtraction: ");
    Serial.println(calc.sub(10, 3));
    blink_once(200);
    Serial.print("Multiplication: ");
    Serial.println(calc.mul(3, 3));
    blink_once(200);
    Serial.print("Division: ");
    Serial.println(calc.div(100, 3));
    blink_once(200);
}

#endif
<|endoftext|>


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

#include "views/controls/button/native_button_gtk.h"

#include <gtk/gtk.h>

#include <vector>

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/button/native_button.h"
#include "views/controls/button/radio_button.h"
#include "views/controls/native/native_view_host_gtk.h"
#include "views/widget/widget.h"

namespace views {

NativeButtonGtk::NativeButtonGtk(NativeButton* native_button)
    : native_button_(native_button) {
  // Associates the actual GtkWidget with the native_button so the native_button
  // is the one considered as having the focus (not the wrapper) when the
  // GtkWidget is focused directly (with a click for example).
  set_focus_view(native_button);
}

NativeButtonGtk::~NativeButtonGtk() {
}

void NativeButtonGtk::UpdateLabel() {
  if (!native_view())
    return;

  gtk_button_set_label(GTK_BUTTON(native_view()),
                       WideToUTF8(native_button_->label()).c_str());
  preferred_size_ = gfx::Size();
}

void NativeButtonGtk::UpdateFont() {
  if (!native_view())
    return;

  PangoFontDescription* pfd =
      gfx::Font::PangoFontFromGfxFont(native_button_->font());
  gtk_widget_modify_font(native_view(), pfd);
  pango_font_description_free(pfd);
  preferred_size_ = gfx::Size();
}

void NativeButtonGtk::UpdateEnabled() {
  SetEnabled(native_button_->IsEnabled());
}

void NativeButtonGtk::UpdateDefault() {
  if (!native_view())
    return;
  if (native_button_->is_default())
    gtk_widget_grab_default(native_view());
}

View* NativeButtonGtk::GetView() {
  return this;
}

void NativeButtonGtk::SetFocus() {
  // Focus the associated widget.
  Focus();
}

bool NativeButtonGtk::UsesNativeLabel() const {
  return true;
}

bool NativeButtonGtk::UsesNativeRadioButtonGroup() const {
  return true;
}

gfx::NativeView NativeButtonGtk::GetTestingHandle() const {
  return native_view();
}

gfx::Size NativeButtonGtk::GetPreferredSize() {
  if (!native_view())
    return gfx::Size();

  if (preferred_size_.IsEmpty()) {
    GtkRequisition size_request = { 0, 0 };
    gtk_widget_size_request(native_view(), &size_request);
    preferred_size_.SetSize(size_request.width, size_request.height);
  }
  return preferred_size_;
}

void NativeButtonGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_button_new();
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);

  // Any push button can become the default button.
  GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_DEFAULT);

  NativeControlCreated(widget);
}

void NativeButtonGtk::NativeControlCreated(GtkWidget* widget) {
  NativeControlGtk::NativeControlCreated(widget);

  UpdateFont();
  UpdateLabel();
  UpdateDefault();
}

// static
void NativeButtonGtk::CallClicked(GtkButton* widget, NativeButtonGtk* button) {
  button->OnClicked();
}

void NativeButtonGtk::OnClicked() {
  native_button_->ButtonPressed();
}

////////////////////////////////////////////////////////////////////////////////
// NativeCheckboxGtk
NativeCheckboxGtk::NativeCheckboxGtk(Checkbox* checkbox)
    : NativeButtonGtk(checkbox),
      deliver_click_event_(true) {
}

void NativeCheckboxGtk::SyncCheckState() {
  checkbox()->SetChecked(
      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_view())));
}

Checkbox* NativeCheckboxGtk::checkbox() {
  return static_cast<Checkbox*>(native_button_);
}

void NativeCheckboxGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_check_button_new();
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);
  NativeControlCreated(widget);
}

void NativeCheckboxGtk::OnClicked() {
  // ignore event if the event is generated by
  // gtk_toggle_button_set_active below.
  if (deliver_click_event_) {
    SyncCheckState();
    NativeButtonGtk::OnClicked();
  }
}

void NativeCheckboxGtk::UpdateDefault() {
  if (!native_view())
    return;
  UpdateChecked();
}

void NativeCheckboxGtk::UpdateChecked() {
  if (!native_view())
    return;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_view()))
      != checkbox()->checked()) {
    // gtk_toggle_button_set_active emites "clicked" signal, which
    // invokes OnClicked method above. deliver_click_event_ flag is used
    // to prevent such signal to invoke OnClicked callback.
    deliver_click_event_ = false;
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(native_view()),
                                 checkbox()->checked());
    deliver_click_event_ = true;
  }
}

////////////////////////////////////////////////////////////////////////////////
NativeRadioButtonGtk::NativeRadioButtonGtk(RadioButton* radio_button)
    : NativeCheckboxGtk(radio_button) {
}

NativeRadioButtonGtk::~NativeRadioButtonGtk() {
}

RadioButton* NativeRadioButtonGtk::radio_button() {
  return static_cast<RadioButton*>(native_button_);
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeCheckboxGtk overrides:

void NativeRadioButtonGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_radio_button_new(NULL);
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);
  g_signal_connect(widget, "toggled",
                   G_CALLBACK(CallToggled), this);
  NativeControlCreated(widget);
}

void NativeRadioButtonGtk::OnToggled() {
  SyncCheckState();
}

// static
void NativeRadioButtonGtk::CallToggled(GtkButton* widget,
                                       NativeRadioButtonGtk* button) {
  button->OnToggled();
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeButtonWrapper overrides:
void NativeRadioButtonGtk::SetGroupFrom(NativeButtonWrapper* wrapper) {
  NativeRadioButtonGtk* peer = static_cast<NativeRadioButtonGtk*>(wrapper);
  GSList* group =
      gtk_radio_button_get_group(GTK_RADIO_BUTTON(peer->native_view()));
  // A group object is managed by gtk framework. It's updated as a radio
  // button is added to, or removed.
  DCHECK(group);
  GtkRadioButton* this_radio_button = GTK_RADIO_BUTTON(native_view());
  if (!g_slist_find(group, this_radio_button))
    gtk_radio_button_set_group(this_radio_button, group);
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeControlGtk overrides:
void NativeRadioButtonGtk::ViewHierarchyChanged(bool is_add,
                                                View *parent, View *child) {
  NativeControlGtk::ViewHierarchyChanged(is_add, parent, child);

  // look for the same group and update
  if (is_add && child == this) {
    View* container = GetParent();
    while (container && container->GetParent())
      container = container->GetParent();
    if (container) {
      std::vector<View*> other;
      container->GetViewsWithGroup(native_button_->GetGroup(), &other);
      for (std::vector<View*>::iterator i = other.begin();
           i != other.end();
           ++i) {
        if (*i != native_button_) {
          if ((*i)->GetClassName() != RadioButton::kViewClassName) {
            NOTREACHED() << "radio-button has same group as other non "
                "radio-button views.";
            continue;
          }
          // Join the group
          NativeButtonWrapper* wrapper =
              static_cast<RadioButton*>(*i)->native_wrapper();
          SetGroupFrom(wrapper);
          break;
        }
      }
    }

    // Sync the state after setting the group because single radio button
    // is always active.
    SyncCheckState();
  }
}

////////////////////////////////////////////////////////////////////////////////
// NativeButtonWrapper

// static
int NativeButtonWrapper::GetFixedWidth() {
  // TODO(brettw) implement this properly.
  return 10;
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateNativeButtonWrapper(
    NativeButton* native_button) {
  return new NativeButtonGtk(native_button);
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateCheckboxWrapper(
    Checkbox* checkbox) {
  return new NativeCheckboxGtk(checkbox);
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateRadioButtonWrapper(
    RadioButton* radio_button) {
  return new NativeRadioButtonGtk(radio_button);
}

}  // namespace views
<commit_msg>Fix a bug that caused a crash by NULL pointer dereference.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "views/controls/button/native_button_gtk.h"

#include <gtk/gtk.h>

#include <vector>

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/button/native_button.h"
#include "views/controls/button/radio_button.h"
#include "views/controls/native/native_view_host_gtk.h"
#include "views/widget/widget.h"

namespace views {

NativeButtonGtk::NativeButtonGtk(NativeButton* native_button)
    : native_button_(native_button) {
  // Associates the actual GtkWidget with the native_button so the native_button
  // is the one considered as having the focus (not the wrapper) when the
  // GtkWidget is focused directly (with a click for example).
  set_focus_view(native_button);
}

NativeButtonGtk::~NativeButtonGtk() {
}

void NativeButtonGtk::UpdateLabel() {
  if (!native_view())
    return;

  gtk_button_set_label(GTK_BUTTON(native_view()),
                       WideToUTF8(native_button_->label()).c_str());
  preferred_size_ = gfx::Size();
}

void NativeButtonGtk::UpdateFont() {
  if (!native_view())
    return;

  PangoFontDescription* pfd =
      gfx::Font::PangoFontFromGfxFont(native_button_->font());
  gtk_widget_modify_font(native_view(), pfd);
  pango_font_description_free(pfd);
  preferred_size_ = gfx::Size();
}

void NativeButtonGtk::UpdateEnabled() {
  SetEnabled(native_button_->IsEnabled());
}

void NativeButtonGtk::UpdateDefault() {
  if (!native_view())
    return;
  if (native_button_->is_default())
    gtk_widget_grab_default(native_view());
}

View* NativeButtonGtk::GetView() {
  return this;
}

void NativeButtonGtk::SetFocus() {
  // Focus the associated widget.
  Focus();
}

bool NativeButtonGtk::UsesNativeLabel() const {
  return true;
}

bool NativeButtonGtk::UsesNativeRadioButtonGroup() const {
  return true;
}

gfx::NativeView NativeButtonGtk::GetTestingHandle() const {
  return native_view();
}

gfx::Size NativeButtonGtk::GetPreferredSize() {
  if (!native_view())
    return gfx::Size();

  if (preferred_size_.IsEmpty()) {
    GtkRequisition size_request = { 0, 0 };
    gtk_widget_size_request(native_view(), &size_request);
    preferred_size_.SetSize(size_request.width, size_request.height);
  }
  return preferred_size_;
}

void NativeButtonGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_button_new();
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);

  // Any push button can become the default button.
  GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_DEFAULT);

  NativeControlCreated(widget);
}

void NativeButtonGtk::NativeControlCreated(GtkWidget* widget) {
  NativeControlGtk::NativeControlCreated(widget);

  UpdateFont();
  UpdateLabel();
  UpdateDefault();
}

// static
void NativeButtonGtk::CallClicked(GtkButton* widget, NativeButtonGtk* button) {
  button->OnClicked();
}

void NativeButtonGtk::OnClicked() {
  native_button_->ButtonPressed();
}

////////////////////////////////////////////////////////////////////////////////
// NativeCheckboxGtk
NativeCheckboxGtk::NativeCheckboxGtk(Checkbox* checkbox)
    : NativeButtonGtk(checkbox),
      deliver_click_event_(true) {
}

void NativeCheckboxGtk::SyncCheckState() {
  checkbox()->SetChecked(
      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_view())));
}

Checkbox* NativeCheckboxGtk::checkbox() {
  return static_cast<Checkbox*>(native_button_);
}

void NativeCheckboxGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_check_button_new();
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);
  NativeControlCreated(widget);
}

void NativeCheckboxGtk::OnClicked() {
  // ignore event if the event is generated by
  // gtk_toggle_button_set_active below.
  if (deliver_click_event_) {
    SyncCheckState();
    NativeButtonGtk::OnClicked();
  }
}

void NativeCheckboxGtk::UpdateDefault() {
  if (!native_view())
    return;
  UpdateChecked();
}

void NativeCheckboxGtk::UpdateChecked() {
  if (!native_view())
    return;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_view()))
      != checkbox()->checked()) {
    // gtk_toggle_button_set_active emites "clicked" signal, which
    // invokes OnClicked method above. deliver_click_event_ flag is used
    // to prevent such signal to invoke OnClicked callback.
    deliver_click_event_ = false;
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(native_view()),
                                 checkbox()->checked());
    deliver_click_event_ = true;
  }
}

////////////////////////////////////////////////////////////////////////////////
NativeRadioButtonGtk::NativeRadioButtonGtk(RadioButton* radio_button)
    : NativeCheckboxGtk(radio_button) {
}

NativeRadioButtonGtk::~NativeRadioButtonGtk() {
}

RadioButton* NativeRadioButtonGtk::radio_button() {
  return static_cast<RadioButton*>(native_button_);
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeCheckboxGtk overrides:

void NativeRadioButtonGtk::CreateNativeControl() {
  GtkWidget* widget = gtk_radio_button_new(NULL);
  g_signal_connect(widget, "clicked",
                   G_CALLBACK(CallClicked), this);
  g_signal_connect(widget, "toggled",
                   G_CALLBACK(CallToggled), this);
  NativeControlCreated(widget);
}

void NativeRadioButtonGtk::OnToggled() {
  SyncCheckState();
}

// static
void NativeRadioButtonGtk::CallToggled(GtkButton* widget,
                                       NativeRadioButtonGtk* button) {
  button->OnToggled();
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeButtonWrapper overrides:
void NativeRadioButtonGtk::SetGroupFrom(NativeButtonWrapper* wrapper) {
  NativeRadioButtonGtk* peer = static_cast<NativeRadioButtonGtk*>(wrapper);
  GSList* group =
      gtk_radio_button_get_group(GTK_RADIO_BUTTON(peer->native_view()));
  // A group object is managed by gtk framework. It's updated as a radio
  // button is added to, or removed.
  DCHECK(group);
  GtkRadioButton* this_radio_button = GTK_RADIO_BUTTON(native_view());
  if (!g_slist_find(group, this_radio_button))
    gtk_radio_button_set_group(this_radio_button, group);
}

////////////////////////////////////////////////////////////////////////////////
// NativeRadioButtonGtk, NativeControlGtk overrides:
void NativeRadioButtonGtk::ViewHierarchyChanged(bool is_add,
                                                View *parent, View *child) {
  NativeControlGtk::ViewHierarchyChanged(is_add, parent, child);

  // look for the same group and update
  if (is_add && child == this) {
    View* container = GetParent();
    while (container && container->GetParent())
      container = container->GetParent();
    if (container) {
      std::vector<View*> other;
      container->GetViewsWithGroup(native_button_->GetGroup(), &other);
      for (std::vector<View*>::iterator i = other.begin();
           i != other.end();
           ++i) {
        if (*i != native_button_) {
          if ((*i)->GetClassName() != RadioButton::kViewClassName) {
            NOTREACHED() << "radio-button has same group as other non "
                "radio-button views.";
            continue;
          }
          // Join the group, if the peer's native wrapper is present.
          // A button without wrapper will be added to the group in
          // its own ViewHierachyChanged.
          NativeButtonWrapper* wrapper =
              static_cast<RadioButton*>(*i)->native_wrapper();
          if (wrapper) {
            SetGroupFrom(wrapper);
            break;
          }
        }
      }
    }

    // Sync the state after setting the group because single radio button
    // is always active.
    SyncCheckState();
  }
}

////////////////////////////////////////////////////////////////////////////////
// NativeButtonWrapper

// static
int NativeButtonWrapper::GetFixedWidth() {
  // TODO(brettw) implement this properly.
  return 10;
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateNativeButtonWrapper(
    NativeButton* native_button) {
  return new NativeButtonGtk(native_button);
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateCheckboxWrapper(
    Checkbox* checkbox) {
  return new NativeCheckboxGtk(checkbox);
}

// static
NativeButtonWrapper* NativeButtonWrapper::CreateRadioButtonWrapper(
    RadioButton* radio_button) {
  return new NativeRadioButtonGtk(radio_button);
}

}  // namespace views
<|endoftext|>


<commit_before>#include <X86/Idt.hh>
#include <X86/Assembly.hh>
#include <Memory.hh>

#include <Interrupt.hh>
#include <Power.hh>
#include <Debug.hh>

#include <StackTrace.hh>

extern IdtPointer idtPointer;

// Idt descriptors
static IdtEntry idtEntries[NUMIDT];
IdtPointer idtPointer;

extern "C" InterruptFrame* x86_isr_dispatcher(InterruptFrame* frame);
extern "C" void x86_isr_init(int n, void (*handler)());

#include "InterruptVectorsInit.icc"

static void
pageFault(InterruptFrame* frame)
{
   uint32_t cr2 = getCr2();

   if ((frame->error & 0x1) == 0 && Memory::handlePageFault(cr2, frame))
   {
#ifdef DEBUG
      printf("Page fault handled: %p\n", (void* )cr2);
#endif
      return;
   }

   printf("\n");
   frame->print();

   printf("\nPage fault: %s\n", (frame->error & (1 << 0)) ? "protection violation" : "page not present");
   printf("%s 0x%x from 0x%x in %s mode\nError Code: 0x%x\n",
	  (frame->error & (1 << 1)) ? "Writing" : "Reading",
	  cr2, frame->rip,
	  (frame->error & (1 << 2)) ? "user" : "supervisor",
	  frame->error);

   StackTrace::printStackTrace(reinterpret_cast<void*>(frame->ebp));

   Power::halt();
}

static void
defaultIsr(InterruptFrame* frame)
{
   // TODO: make a list of handlers and register them there to be run from dispatcher
   if (frame->interrupt == 14)
   {
      pageFault(frame);
      return;
   }

   if (frame->error == 0)
   {
      printf("\n");
      frame->print();

      Debug::panic("\n\nUnhandled Interrupt: %u\n", frame->interrupt);
   }
   else
   {
      Debug::panic("\n\nUnhandled Interrupt: %u, Error Code: 0x%x\n", frame->interrupt, frame->error);
   }

   // printf("\nInterrupt frame:\n");
   // frame->print();
   // printf("\n");
}

InterruptFrame*
x86_isr_dispatcher(InterruptFrame* frame)
{
   KASSERT(Interrupt::getInterruptLevel() > 0);

   // XXX hardcoded hack
   if (frame->interrupt >= 32 && frame->interrupt < 48)
   {
      Interrupt::handleInterrupt(frame->interrupt - 32);
      return frame;
   }

   defaultIsr(frame);

   KASSERT(Interrupt::getInterruptLevel() > 0);

   return frame;
}

void
x86_isr_init(int n, void (*handler)())
{
   idtEntries[n].baseLow = (uint16_t)((uint32_t)(handler) & 0xffff);
   idtEntries[n].baseHigh = (uint16_t)(((uint32_t)(handler) >> 16) & 0xffff);

   idtEntries[n].selector = 0x08;
   idtEntries[n].flags = 0x8e;

   // zero filled
   idtEntries[n].reserved = 0;
}

void
initInterrupts()
{
   idtPointer.base = (uint32_t )&idtEntries;
   idtPointer.limit = sizeof(IdtEntry) * NUMIDT - 1;

   // generated function
   initInterruptVectors();

   idtinit();
}
<commit_msg>Rename classless function to c-style name<commit_after>#include <X86/Idt.hh>
#include <X86/Assembly.hh>
#include <Memory.hh>

#include <Interrupt.hh>
#include <Power.hh>
#include <Debug.hh>

#include <StackTrace.hh>

extern IdtPointer idtPointer;

// Idt descriptors
static IdtEntry idtEntries[NUMIDT];
IdtPointer idtPointer;

extern "C" InterruptFrame* x86_isr_dispatcher(InterruptFrame* frame);
extern "C" void x86_isr_init(int n, void (*handler)());

#include "InterruptVectorsInit.icc"

// XXX this should be refactored to be MI
//
static void
x86_isr_page_fault(InterruptFrame* frame)
{
   uint32_t cr2 = getCr2();

   if ((frame->error & 0x1) == 0 && Memory::handlePageFault(cr2, frame))
   {
#ifdef DEBUG
      printf("Page fault handled: %p\n", (void* )cr2);
#endif
      return;
   }

   printf("\n");
   frame->print();

   printf("\nPage fault: %s\n", (frame->error & (1 << 0)) ? "protection violation" : "page not present");
   printf("%s 0x%x from 0x%x in %s mode\nError Code: 0x%x\n",
	  (frame->error & (1 << 1)) ? "Writing" : "Reading",
	  cr2, frame->rip,
	  (frame->error & (1 << 2)) ? "user" : "supervisor",
	  frame->error);

   StackTrace::printStackTrace(reinterpret_cast<void*>(frame->ebp));

   Power::halt();
}

static void
x86_isr_default_handler(InterruptFrame* frame)
{
   // TODO: make a list of handlers and register them there to be run from dispatcher
   if (frame->interrupt == 14)
   {
      x86_isr_page_fault(frame);
      return;
   }

   if (frame->error == 0)
   {
      printf("\n");
      frame->print();

      Debug::panic("\n\nUnhandled Interrupt: %u\n", frame->interrupt);
   }
   else
   {
      Debug::panic("\n\nUnhandled Interrupt: %u, Error Code: 0x%x\n", frame->interrupt, frame->error);
   }

   // printf("\nInterrupt frame:\n");
   // frame->print();
   // printf("\n");
}

InterruptFrame*
x86_isr_dispatcher(InterruptFrame* frame)
{
   KASSERT(Interrupt::getInterruptLevel() > 0);

   // XXX hardcoded hack
   if (frame->interrupt >= 32 && frame->interrupt < 48)
   {
      Interrupt::handleInterrupt(frame->interrupt - 32);
      return frame;
   }

   x86_isr_default_handler(frame);

   KASSERT(Interrupt::getInterruptLevel() > 0);

   return frame;
}

void
x86_isr_init(int n, void (*handler)())
{
   idtEntries[n].baseLow = (uint16_t)((uint32_t)(handler) & 0xffff);
   idtEntries[n].baseHigh = (uint16_t)(((uint32_t)(handler) >> 16) & 0xffff);

   idtEntries[n].selector = 0x08;
   idtEntries[n].flags = 0x8e;

   // zero filled
   idtEntries[n].reserved = 0;
}

void
initInterrupts()
{
   idtPointer.base = (uint32_t )&idtEntries;
   idtPointer.limit = sizeof(IdtEntry) * NUMIDT - 1;

   // generated function
   initInterruptVectors();

   idtinit();
}
<|endoftext|>


<commit_before>#ifndef GNR_FIND_HPP
# define GNR_FIND_HPP
# pragma once

#include <algorithm>

#include <type_traits>

namespace gnr
{

namespace detail
{

template <typename T>
static constexpr T* begin(T& value) noexcept
{
  return &value;
}

template <typename T, std::size_t N>
static constexpr typename std::remove_all_extents<T>::type*
begin(T (&array)[N]) noexcept
{
  return begin(*array);
}

template <typename T>
static constexpr T* end(T& value) noexcept
{
  return &value + 1;
}

template <typename T, std::size_t N>
static constexpr typename std::remove_all_extents<T>::type*
end(T (&array)[N]) noexcept
{
  return end(array[N - 1]);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, int)
  noexcept(noexcept(c.find(k))) -> decltype(c.find(k))
{
  return c.find(k);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, char,
  std::enable_if_t<!std::is_array<Container>{}>* = {})
  noexcept(noexcept(std::find(std::begin(c), std::end(c), k))) ->
  decltype(std::find(std::begin(c), std::end(c), k))
{
  return std::find(std::begin(c), std::end(c), k);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, char,
  std::enable_if_t<std::is_array<Container>{}>* = {})
  noexcept(noexcept(std::find(begin(c), end(c), k))) ->
  decltype(std::find(begin(c), end(c), k))
{
  return std::find(begin(c), end(c), k);
}

}

template <class Container, class Key>
inline auto any_find(Container& c, Key const& k) noexcept(
  noexcept(detail::find(c, k, 0))
)
{
  return detail::find(c, k, 0);
}

template <class Container, class Key, typename F>
inline void any_find(Container& c, Key const& k, F&& f) noexcept(
  noexcept(f(detail::find(c, k, 0)))
)
{
  f(detail::find(c, k, 0));
}

}

#endif // GNR_FIND_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_FIND_HPP
# define GNR_FIND_HPP
# pragma once

#include <algorithm>

#include <type_traits>

namespace gnr
{

namespace detail
{

template <typename T>
static constexpr T* begin(T& value) noexcept
{
  return &value;
}

template <typename T, std::size_t N>
static constexpr typename std::remove_all_extents<T>::type*
begin(T (&array)[N]) noexcept
{
  return begin(*array);
}

template <typename T>
static constexpr T* end(T& value) noexcept
{
  return &value + 1;
}

template <typename T, std::size_t N>
static constexpr typename std::remove_all_extents<T>::type*
end(T (&array)[N]) noexcept
{
  return end(array[N - 1]);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, int)
  noexcept(noexcept(c.find(k))) -> decltype(c.find(k))
{
  return c.find(k);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, char,
  std::enable_if_t<!std::is_array<Container>{}>* = {})
  noexcept(noexcept(std::find(std::begin(c), std::end(c), k))) ->
  decltype(std::find(std::begin(c), std::end(c), k))
{
  return std::find(std::begin(c), std::end(c), k);
}

template <class Container, class Key>
inline auto find(Container& c, Key const& k, char,
  std::enable_if_t<std::is_array<Container>{}>* = {})
  noexcept(noexcept(std::find(begin(c), end(c), k))) ->
  decltype(std::find(begin(c), end(c), k))
{
  return std::find(begin(c), end(c), k);
}

}

template <class Container, class Key>
inline auto any_find(Container& c, Key const& k) noexcept(
  noexcept(detail::find(c, k, 0))
)
{
  return detail::find(c, k, 0);
}

template <class Container, class Key, typename F>
inline void any_find(Container& c, Key const& k, F&& f) noexcept(
  noexcept(f(detail::find(c, k, 0)))
)
{
  f(detail::find(c, k, 0));
}

}

#endif // GNR_FIND_HPP
<|endoftext|>