<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *
 *  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 Willow Garage, 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.
 *
 * ww
 *
 */

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/features/esf.h>
#include <pcl/features/impl/esf.hpp>

// Instantiations of specific point types
#ifdef PCL_ONLY_CORE_POINT_TYPES
  PCL_INSTANTIATE_PRODUCT(ESFEstimation, ((pcl::PointXYZ)(pcl::PointXYZI)(pcl::PointXYZRGBA)(pcl::PointNormal))((pcl::Normal)(pcl::PointNormal))((pcl::ESFSignature640)))
#else
  PCL_INSTANTIATE_PRODUCT(ESFEstimation, (PCL_XYZ_POINT_TYPES)((pcl::ESFSignature640)))
#endif
<commit_msg>Fixed instantiation only using core types.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *
 *  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 Willow Garage, 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.
 *
 * ww
 *
 */

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/features/esf.h>
#include <pcl/features/impl/esf.hpp>

// Instantiations of specific point types
#ifdef PCL_ONLY_CORE_POINT_TYPES
  PCL_INSTANTIATE_PRODUCT(ESFEstimation, ((pcl::PointXYZ)(pcl::PointXYZI)(pcl::PointXYZRGBA)(pcl::PointNormal))((pcl::ESFSignature640)))
#else
  PCL_INSTANTIATE_PRODUCT(ESFEstimation, (PCL_XYZ_POINT_TYPES)((pcl::ESFSignature640)))
#endif
<|endoftext|>


<commit_before>/*
 * PrimeSieve.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#include "PrimeSieve.h"
#include "defs.h"
#include "ParallelPrimeSieve.h"
#include "pmath.h"
#include "ResetSieve.h"
#include "PrimeNumberFinder.h"
#include "PrimeNumberGenerator.h"

#include <stdexcept>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>

PrimeSieve::PrimeSieve() :
  startNumber_(0), stopNumber_(0),
    sieveSize_(defs::SIEVESIZE_PRIMENUMBERFINDER), flags_(COUNT_PRIMES),
    timeElapsed_(0.0) {
  parent_ = this;
  this->reset();
}

/**
 * Is used by ParallelPrimeSieve which uses multiple PrimeSieve
 * objects and threads to sieve primes in parallel.
 * @see ParallelPrimeSieve::sieve()
 */
PrimeSieve::PrimeSieve(uint64_t startNumber, uint64_t stopNumber,
    ParallelPrimeSieve* parent) :
  sieveSize_(parent->sieveSize_), flags_(parent->flags_), timeElapsed_(0.0),
    callback_imp(parent->callback_imp),
    callback_oop(parent->callback_oop),
    cbObj_(parent->cbObj_),
    parent_(parent) {
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->reset();
}

uint64_t PrimeSieve::getStartNumber() const {
  return startNumber_;
}

uint64_t PrimeSieve::getStopNumber() const {
  return stopNumber_;
}

/**
 * Get the sieve size in KiloBytes.
 */
uint32_t PrimeSieve::getSieveSize() const {
  return sieveSize_ / 1024;
}

/**
 * Get the current set user flags.
 */
uint32_t PrimeSieve::getFlags() const {
  // clear out internal flags
  return flags_ & ((1u << 20) - 1);
}

/**
 * Generate the prime numbers between startNumber and stopNumber and
 * call a callback function for each prime.
 */
void PrimeSieve::generatePrimes(uint64_t startNumber, uint64_t stopNumber,
    void (*callback)(uint64_t)) {
  if (callback == NULL)
    throw std::invalid_argument("callback must not be NULL");
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(CALLBACK_PRIMES_IMP);
  callback_imp = callback;
  this->sieve();
}

/**
 * Generate the prime numbers between startNumber and stopNumber and
 * call an OOP style callback function for each prime.
 */
void PrimeSieve::generatePrimes(uint64_t startNumber, uint64_t stopNumber,
    void (*callback)(uint64_t, void*), void* cbObj) {
  if (callback == NULL)
    throw std::invalid_argument("callback must not be NULL");
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(CALLBACK_PRIMES_OOP);
  callback_oop = callback;
  cbObj_ = cbObj;
  this->sieve();
}

/**
 * Get the count of prime numbers between startNumber and stopNumber.
 */
uint64_t PrimeSieve::getPrimeCount(uint64_t startNumber, uint64_t stopNumber) {
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(COUNT_PRIMES);
  this->sieve();
  return this->getPrimeCount();
}

/**
 * Get the count of prime numbers between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getPrimeCount() const {
  return counts_[0];
}

/**
 * Get the count of twin primes between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getTwinCount() const {
  return counts_[1];
}

/**
 * Get the count of prime triplets between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getTripletCount() const {
  return counts_[2];
}

/**
 * Get the count of prime quadruplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getQuadrupletCount() const {
  return counts_[3];
}

/**
 * Get the count of prime quintuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getQuintupletCount() const {
  return counts_[4];
}

/**
 * Get the count of prime sextuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getSextupletCount() const {
  return counts_[5];
}

/**
 * Get the count of prime septuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getSeptupletCount() const {
  return counts_[6];
}

/**
 * Get the count of prime numbers or prime k-tuplets between
 * startNumber and stopNumber after having called sieve().
 * e.g type = 0 for prime numbers,
 *     type = 1 for twin primes,
 *     type = 2 for prime triplets,
 *     ...
 * @param type <= 7
 */
uint64_t PrimeSieve::getCounts(uint32_t type) const {
  if (type >= COUNTS_SIZE)
    throw std::out_of_range("getCounts(uint32_t) type out of range");
  return counts_[type];
}

/**
 * Get the time elapsed in seconds of the last sieve session.
 */
double PrimeSieve::getTimeElapsed() const {
  return timeElapsed_;
}

/**
 * Set a start number for sieving.
 * @pre startNumber < (2^64-1) - (2^32-1) * 10
 */
void PrimeSieve::setStartNumber(uint64_t startNumber) {
  // EratBig and EratMedium stopNumber limit
  if (startNumber >= UINT64_MAX - UINT32_MAX * UINT64_C(10))
    throw std::invalid_argument("START must be < (2^64-1) - (2^32-1) * 10");
  startNumber_ = startNumber;
}

/**
 * Set a stop number for sieving.
 * @pre stopNumber < (2^64-1) - (2^32-1) * 10
 */
void PrimeSieve::setStopNumber(uint64_t stopNumber) {
  // EratBig and EratMedium stopNumber limit
  if (stopNumber >= UINT64_MAX - UINT32_MAX * UINT64_C(10))
    throw std::invalid_argument("STOP must be < (2^64-1) - (2^32-1) * 10");
  stopNumber_ = stopNumber;
}

/**
 * Set the size (in KiloBytes) of the sieve of Eratosthenes array.
 * The best performance is achieved with a sieve size that matches
 * the CPU's L1 cache size (usually 32 or 64 KB) when sieving < 10^14
 * and a sieve size of the CPU's L2 cache size above.
 *
 * Default sieveSize = 64 KiloBytes
 *
 * @pre sieveSize must be a power of 2,
 *      sieveSize >= 1 KiloByte,
 *      sieveSize <= 8192 KiloBytes.
 */
void PrimeSieve::setSieveSize(uint32_t sieveSize) {
  // SieveOfEratosthenes lower sieve size limit AND
  // EratBig upper sieveSize limit
  if (sieveSize < 1 || sieveSize > 8192)
    throw std::invalid_argument("sieve size must be >= 1 and <= 8192 KiloBytes");
  // EratBig requires a power of 2 sieve size
  if (!isPowerOf2(sieveSize))
    throw std::invalid_argument("sieve size must be a power of 2");
  // convert to Bytes for SieveOfEratosthenes objects
  sieveSize_ = sieveSize * 1024;
}

/**
 * Set the flags (settings) of PrimeSieve.
 * @param flags
 *   PrimeSieve::COUNT_PRIMES      OR (bitwise '|')
 *   PrimeSieve::COUNT_TWINS       OR
 *   PrimeSieve::COUNT_TRIPLETS    OR
 *   PrimeSieve::COUNT_QUADRUPLETS OR
 *   PrimeSieve::COUNT_QUINTUPLETS OR
 *   PrimeSieve::COUNT_SEXTUPLETS  OR
 *   PrimeSieve::COUNT_SEPTUPLETS  OR
 *   PrimeSieve::PRINT_PRIMES      OR
 *   PrimeSieve::PRINT_TWINS       OR
 *   PrimeSieve::PRINT_TRIPLETS    OR
 *   PrimeSieve::PRINT_QUADRUPLETS OR
 *   PrimeSieve::PRINT_QUINTUPLETS OR
 *   PrimeSieve::PRINT_SEXTUPLETS  OR
 *   PrimeSieve::PRINT_SEPTUPLETS  OR
 *   PrimeSieve::PRINT_STATUS.
 */
void PrimeSieve::setFlags(uint32_t flags) {
  if (flags >= (1u << 20))
    throw std::invalid_argument("invalid flags");
  flags_ = flags;
}

void PrimeSieve::reset() {
  segments_ = 0;
  for (uint32_t i = 0; i < COUNTS_SIZE; i++)
    counts_[i] = 0;
  status_ = -1.0;
  parent_->doStatus(0);
}

/**
 * Print the status (in percent) of the sieving process
 * to the standard output.
 */
void PrimeSieve::doStatus(uint64_t segment) {
  segments_ += segment;
  double old = status_;
  status_ = static_cast<double> (segments_) /
            static_cast<double> (1 + stopNumber_ - startNumber_) * 100.0;
  if (static_cast<int> (status_) > 99)
    status_ = 100.0;
  if ((flags_ & PRINT_STATUS) &&
      static_cast<int> (status_) > static_cast<int> (old)) {
    std::cout << '\r' << static_cast<int> (status_) << '%' << std::flush;
  }
}

void PrimeSieve::doSmallPrime(uint32_t low, uint32_t high, uint32_t type,
    std::string prime) {
  if (startNumber_ <= low && stopNumber_ >= high) {
    if (flags_ & (COUNT_PRIMES << type))
      counts_[type]++;
    if (flags_ & (PRINT_PRIMES << type))
      std::cout << prime << std::endl;
    else if (flags_ & CALLBACK_PRIMES_IMP)
      this->callback_imp(prime[0]-'0');
    else if (flags_ & CALLBACK_PRIMES_OOP)
      this->callback_oop(prime[0]-'0', cbObj_);
  }
}

/**
 * Sieve the prime numbers and/or prime k-tuplets between startNumber
 * and stopNumber.
 */
void PrimeSieve::sieve() {
  if (stopNumber_ < startNumber_)
    throw std::invalid_argument("STOP must be >= START");
  timeElapsed_ = static_cast<double> (std::clock());
  this->reset();

  // small primes have to be examined manually
  if (startNumber_ <= 5) {
    this->doSmallPrime(2,  2, 0, "2");
    this->doSmallPrime(3,  3, 0, "3");
    this->doSmallPrime(5,  5, 0, "5");
    this->doSmallPrime(3,  5, 1, "(3, 5)");
    this->doSmallPrime(5,  7, 1, "(5, 7)");
    this->doSmallPrime(5, 11, 2, "(5, 7, 11)");
    this->doSmallPrime(5, 13, 3, "(5, 7, 11, 13)");
    this->doSmallPrime(5, 17, 4, "(5, 7, 11, 13, 17)");
  }

  if (stopNumber_ >= 7) {
    ResetSieve resetSieve(this);
    // used to sieve the prime numbers and prime k-tuplets between
    // startNumber_ and stopNumber_
    PrimeNumberFinder primeNumberFinder(this, &resetSieve);

    if (isqrt(stopNumber_) > resetSieve.getLimit()) {
      /// used to generate the prime numbers up to stopNumber_^0.5
      /// needed for sieving by primeNumberFinder
      /// @see PrimeNumberGenerator::generate(const uint8_t*, uint32_t)
      PrimeNumberGenerator primeNumberGenerator(&primeNumberFinder);
      std::vector<uint32_t> primes16Bit;
      primes16Bit.push_back(3);
      uint32_t stop = isqrt(primeNumberGenerator.getStopNumber());
      uint32_t keep = isqrt(stop);
      // the following trial division algorithm is used to generate the
      // prime numbers up to stopNumber_^0.25 needed for sieving by
      // primeNumberGenerator. Although the algorithm is never
      // used > 65536 it finds the prime numbers up to 10^7 in 1 second
      // on an Intel Core i5-670 3.46GHz
      for (uint32_t n = 5; n <= stop; n += 2) {
        uint32_t s = isqrt(n);
        uint32_t i = 0;
        for (; primes16Bit[i] <= s && (n % primes16Bit[i]) != 0; i++)
          ;
        if (primes16Bit[i] > s) {
          if (primes16Bit[i] <= keep)
            primes16Bit.push_back(n);
          if (n > resetSieve.getLimit())
            primeNumberGenerator.sieve(n);
        }
      }
      primeNumberGenerator.finish();
    }
    primeNumberFinder.finish();
  }

  // set status_ to 100.0 (percent)
  parent_->doStatus(10);
  timeElapsed_ = (static_cast<double> (std::clock()) - timeElapsed_) /
      static_cast<double> (CLOCKS_PER_SEC);
}
<commit_msg>updated<commit_after>/*
 * PrimeSieve.cpp -- This file is part of primesieve
 *
 * Copyright (C) 2011 Kim Walisch, <kim.walisch@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#include "PrimeSieve.h"
#include "defs.h"
#include "ParallelPrimeSieve.h"
#include "pmath.h"
#include "ResetSieve.h"
#include "PrimeNumberFinder.h"
#include "PrimeNumberGenerator.h"

#include <stdexcept>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>

PrimeSieve::PrimeSieve() :
  startNumber_(0), stopNumber_(0),
    sieveSize_(defs::SIEVESIZE_PRIMENUMBERFINDER), flags_(COUNT_PRIMES),
    timeElapsed_(0.0) {
  parent_ = this;
  this->reset();
}

/**
 * Is used by ParallelPrimeSieve which uses multiple PrimeSieve
 * objects and threads to sieve primes in parallel.
 * @see ParallelPrimeSieve::sieve()
 */
PrimeSieve::PrimeSieve(uint64_t startNumber, uint64_t stopNumber,
    ParallelPrimeSieve* parent) :
  sieveSize_(parent->sieveSize_), flags_(parent->flags_), timeElapsed_(0.0),
    callback_imp(parent->callback_imp),
    callback_oop(parent->callback_oop),
    cbObj_(parent->cbObj_),
    parent_(parent) {
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->reset();
}

uint64_t PrimeSieve::getStartNumber() const {
  return startNumber_;
}

uint64_t PrimeSieve::getStopNumber() const {
  return stopNumber_;
}

/**
 * Get the sieve size in KiloBytes.
 */
uint32_t PrimeSieve::getSieveSize() const {
  return sieveSize_ / 1024;
}

/**
 * Get the current set user flags.
 */
uint32_t PrimeSieve::getFlags() const {
  // clear out internal flags
  return flags_ & ((1u << 20) - 1);
}

/**
 * Generate the prime numbers between startNumber and stopNumber and
 * call a callback function for each prime.
 */
void PrimeSieve::generatePrimes(uint64_t startNumber, uint64_t stopNumber,
    void (*callback)(uint64_t)) {
  if (callback == NULL)
    throw std::invalid_argument("callback must not be NULL");
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(CALLBACK_PRIMES_IMP);
  callback_imp = callback;
  this->sieve();
}

/**
 * Generate the prime numbers between startNumber and stopNumber and
 * call an OOP style callback function for each prime.
 */
void PrimeSieve::generatePrimes(uint64_t startNumber, uint64_t stopNumber,
    void (*callback)(uint64_t, void*), void* cbObj) {
  if (callback == NULL)
    throw std::invalid_argument("callback must not be NULL");
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(CALLBACK_PRIMES_OOP);
  callback_oop = callback;
  cbObj_ = cbObj;
  this->sieve();
}

/**
 * Get the count of prime numbers between startNumber and stopNumber.
 */
uint64_t PrimeSieve::getPrimeCount(uint64_t startNumber, uint64_t stopNumber) {
  this->setStartNumber(startNumber);
  this->setStopNumber(stopNumber);
  this->setFlags(COUNT_PRIMES);
  this->sieve();
  return this->getPrimeCount();
}

/**
 * Get the count of prime numbers between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getPrimeCount() const {
  return counts_[0];
}

/**
 * Get the count of twin primes between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getTwinCount() const {
  return counts_[1];
}

/**
 * Get the count of prime triplets between startNumber and stopNumber
 * after having called sieve().
 */
uint64_t PrimeSieve::getTripletCount() const {
  return counts_[2];
}

/**
 * Get the count of prime quadruplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getQuadrupletCount() const {
  return counts_[3];
}

/**
 * Get the count of prime quintuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getQuintupletCount() const {
  return counts_[4];
}

/**
 * Get the count of prime sextuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getSextupletCount() const {
  return counts_[5];
}

/**
 * Get the count of prime septuplets between startNumber and
 * stopNumber after having called sieve().
 */
uint64_t PrimeSieve::getSeptupletCount() const {
  return counts_[6];
}

/**
 * Get the count of prime numbers or prime k-tuplets between
 * startNumber and stopNumber after having called sieve().
 * e.g type = 0 for prime numbers,
 *     type = 1 for twin primes,
 *     type = 2 for prime triplets,
 *     ...
 * @param type <= 7
 */
uint64_t PrimeSieve::getCounts(uint32_t type) const {
  if (type >= COUNTS_SIZE)
    throw std::out_of_range("getCounts(uint32_t) type out of range");
  return counts_[type];
}

/**
 * Get the time elapsed in seconds of the last sieve session.
 */
double PrimeSieve::getTimeElapsed() const {
  return timeElapsed_;
}

/**
 * Set a start number for sieving.
 * @pre startNumber < (2^64-1) - (2^32-1) * 10
 */
void PrimeSieve::setStartNumber(uint64_t startNumber) {
  // EratBig and EratMedium stopNumber limit
  if (startNumber >= UINT64_MAX - UINT32_MAX * UINT64_C(10))
    throw std::invalid_argument("START must be < (2^64-1) - (2^32-1) * 10");
  startNumber_ = startNumber;
}

/**
 * Set a stop number for sieving.
 * @pre stopNumber < (2^64-1) - (2^32-1) * 10
 */
void PrimeSieve::setStopNumber(uint64_t stopNumber) {
  // EratBig and EratMedium stopNumber limit
  if (stopNumber >= UINT64_MAX - UINT32_MAX * UINT64_C(10))
    throw std::invalid_argument("STOP must be < (2^64-1) - (2^32-1) * 10");
  stopNumber_ = stopNumber;
}

/**
 * Set the size (in KiloBytes) of the sieve of Eratosthenes array.
 * The best performance is achieved with a sieve size that matches
 * the CPU's L1 cache size (usually 32 or 64 KB) when sieving < 10^14
 * and a sieve size of the CPU's L2 cache size above.
 *
 * Default sieveSize = 64 KiloBytes
 *
 * @pre sieveSize must be a power of 2,
 *      sieveSize >= 1 KiloByte,
 *      sieveSize <= 8192 KiloBytes.
 */
void PrimeSieve::setSieveSize(uint32_t sieveSize) {
  // SieveOfEratosthenes lower sieve size limit AND
  // EratBig upper sieveSize limit
  if (sieveSize < 1 || sieveSize > 8192)
    throw std::invalid_argument("sieve size must be >= 1 and <= 8192 KiloBytes");
  // EratBig requires a power of 2 sieve size
  if (!isPowerOf2(sieveSize))
    throw std::invalid_argument("sieve size must be a power of 2");
  // convert to Bytes for SieveOfEratosthenes objects
  sieveSize_ = sieveSize * 1024;
}

/**
 * Set the flags (settings) of PrimeSieve.
 * @param flags
 *   PrimeSieve::COUNT_PRIMES      OR (bitwise '|')
 *   PrimeSieve::COUNT_TWINS       OR
 *   PrimeSieve::COUNT_TRIPLETS    OR
 *   PrimeSieve::COUNT_QUADRUPLETS OR
 *   PrimeSieve::COUNT_QUINTUPLETS OR
 *   PrimeSieve::COUNT_SEXTUPLETS  OR
 *   PrimeSieve::COUNT_SEPTUPLETS  OR
 *   PrimeSieve::PRINT_PRIMES      OR
 *   PrimeSieve::PRINT_TWINS       OR
 *   PrimeSieve::PRINT_TRIPLETS    OR
 *   PrimeSieve::PRINT_QUADRUPLETS OR
 *   PrimeSieve::PRINT_QUINTUPLETS OR
 *   PrimeSieve::PRINT_SEXTUPLETS  OR
 *   PrimeSieve::PRINT_SEPTUPLETS  OR
 *   PrimeSieve::PRINT_STATUS.
 */
void PrimeSieve::setFlags(uint32_t flags) {
  if (flags >= (1u << 20))
    throw std::invalid_argument("invalid flags");
  flags_ = flags;
}

void PrimeSieve::reset() {
  segments_ = 0;
  for (uint32_t i = 0; i < COUNTS_SIZE; i++)
    counts_[i] = 0;
  status_ = -1.0;
  parent_->doStatus(0);
}

/**
 * Print the status (in percent) of the sieving process
 * to the standard output.
 */
void PrimeSieve::doStatus(uint64_t segment) {
  segments_ += segment;
  double old = status_;
  status_ = static_cast<double> (segments_) /
            static_cast<double> (1 + stopNumber_ - startNumber_) * 100.0;
  if (static_cast<int> (status_) > 99)
    status_ = 100.0;
  if ((flags_ & PRINT_STATUS) &&
      static_cast<int> (status_) > static_cast<int> (old)) {
    std::cout << '\r' << static_cast<int> (status_) << '%' << std::flush;
  }
}

void PrimeSieve::doSmallPrime(uint32_t low, uint32_t high, uint32_t type,
    std::string prime) {
  if (startNumber_ <= low && stopNumber_ >= high) {
    if (flags_ & (COUNT_PRIMES << type))
      counts_[type]++;
    if (flags_ & (PRINT_PRIMES << type))
      std::cout << prime << std::endl;
    else if (flags_ & CALLBACK_PRIMES_IMP)
      this->callback_imp(prime[0]-'0');
    else if (flags_ & CALLBACK_PRIMES_OOP)
      this->callback_oop(prime[0]-'0', cbObj_);
  }
}

/**
 * Sieve the prime numbers and/or prime k-tuplets between startNumber
 * and stopNumber.
 */
void PrimeSieve::sieve() {
  if (stopNumber_ < startNumber_)
    throw std::invalid_argument("STOP must be >= START");
  timeElapsed_ = static_cast<double> (std::clock());
  this->reset();

  // small primes have to be examined manually
  if (startNumber_ <= 5) {
    this->doSmallPrime(2,  2, 0, "2");
    this->doSmallPrime(3,  3, 0, "3");
    this->doSmallPrime(5,  5, 0, "5");
    this->doSmallPrime(3,  5, 1, "(3, 5)");
    this->doSmallPrime(5,  7, 1, "(5, 7)");
    this->doSmallPrime(5, 11, 2, "(5, 7, 11)");
    this->doSmallPrime(5, 13, 3, "(5, 7, 11, 13)");
    this->doSmallPrime(5, 17, 4, "(5, 7, 11, 13, 17)");
  }

  if (stopNumber_ >= 7) {
    ResetSieve resetSieve(this);
    // used to sieve the prime numbers and prime k-tuplets between
    // startNumber_ and stopNumber_
    PrimeNumberFinder primeNumberFinder(this, &resetSieve);

    if (isqrt(stopNumber_) > resetSieve.getLimit()) {
      /// used to generate the prime numbers up to stopNumber_^0.5
      /// needed for sieving by primeNumberFinder
      /// @see PrimeNumberGenerator::generate(const uint8_t*, uint32_t)
      PrimeNumberGenerator primeNumberGenerator(&primeNumberFinder);
      std::vector<uint32_t> primes16Bit;
      primes16Bit.push_back(3);
      uint32_t stop = isqrt(primeNumberGenerator.getStopNumber());
      uint32_t keep = isqrt(stop);
      // the following trial division algorithm is used to generate the
      // prime numbers up to stopNumber_^0.25 needed for sieving by
      // primeNumberGenerator. Although the algorithm is never
      // used > 65536 it finds the prime numbers up to 10^7 in 1 second
      // on an Intel Core i5-670 3.46GHz
      for (uint32_t n = 5; n <= stop; n += 2) {
        uint32_t s = isqrt(n);
        uint32_t i = 0;
        for (; primes16Bit[i] <= s && (n % primes16Bit[i]) != 0; i++)
          ;
        if (primes16Bit[i] > s) {
          if (primes16Bit[i] <= keep)
            primes16Bit.push_back(n);
          if (n > resetSieve.getLimit())
            primeNumberGenerator.sieve(n);
        }
      }
      primeNumberGenerator.finish();
    }
    primeNumberFinder.finish();
  }
  // set status_ to 100.0 (percent)
  parent_->doStatus(10);
  timeElapsed_ = (static_cast<double> (std::clock()) - timeElapsed_) /
      static_cast<double> (CLOCKS_PER_SEC);
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C $         */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_mc.C
/// @brief Initialize the memory controller to take over the DRAM
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_draminit_mc.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;

extern "C"
{
///
/// @brief Initialize the MC now that DRAM is up
/// @param[in] i_target, the McBIST of the ports
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_mc( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        auto l_mca = i_target.getChildren<TARGET_TYPE_MCA>();

        FAPI_INF("Start draminit MC");

        // If we don't have any ports, lets go.
        if (l_mca.size() == 0)
        {
            FAPI_INF("No ports? %s", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        // While we're doing the scominit in here, lets do it for all ports before we dump the MCS regs.
        for (auto p : i_target.getChildren<TARGET_TYPE_MCA>())
        {
            mss::mc<TARGET_TYPE_MCS> l_mc;

            // Don't do this yet - leverage the sim inits for the moment
#if 0
            // All the scominit for this MCA
            l_mc.scominit(p);
#endif
            // Setup the MC port/dimm address translation registers
            FAPI_TRY( l_mc.setup_xlate_map(p) );
        }

        for (auto p : l_mca)
        {

            // Setup the read_pointer_delay
            // TK: Do we need to do this in general or is this a place holder until the
            // init file gets here?
            {
                fapi2::buffer<uint64_t> l_data;
                FAPI_TRY( mss::getScom(p, MCA_RECR, l_data) );
                l_data.insertFromRight<MCA_RECR_MBSECCQ_READ_POINTER_DELAY, MCA_RECR_MBSECCQ_READ_POINTER_DELAY_LEN>(0x1);
                FAPI_DBG("writing read pointer delay 0x%016lx %s", l_data, mss::c_str(p));
                FAPI_TRY( mss::putScom(p, MCA_RECR, l_data) );
            }

            // Set the IML Complete bit MBSSQ(3) (SCOM Addr: 0x02011417) to indicate that IML has completed
            // Can't find MBSSQ or the iml_complete bit - asked Steve. Gary VH created this bit as a scratch
            // 'you are hre bit' and it was removed for Nimbus. Gary VH asked for it to be put back in. Not
            // sure if that happened yet. BRS (2/16).

            // Reset addr_mux_sel to “0” to allow the MCA to take control of the DDR interface over from CCS.
            // (Note: this step must remain in this procedure to ensure that data path is placed into mainline
            // mode prior to running memory diagnostics. This step maybe superfluous but not harmful.)
            // Note: addr_mux_sel is set low in p9_mss_draminit(), however that might be a work-around so we
            // set it low here kind of like belt-and-suspenders. BRS
            FAPI_TRY( mss::change_addr_mux_sel(p, mss::LOW) );

            // Re-enable port fails. Turned off in draminit_training
            FAPI_TRY( mss::change_port_fail_disable(p, mss::OFF ) );

            // Step Two.1: Check RCD protect time on RDIMM and LRDIMM
            // Step Two.2: Enable address inversion on each MBA for ALL CARDS

            // Start the refresh engines by setting MBAREF0Q(0) = “1”. Note that the remaining bits in
            // MBAREF0Q should retain their initialization values.
            FAPI_TRY( mss::change_refresh_enable(p, mss::HIGH) );

            // Power management is handled in the init file. (or should be BRS)

            // Enabling periodic calibration
            FAPI_TRY( mss::enable_periodic_cal(p) );

            // Step Six: Setup Control Bit ECC
            FAPI_TRY( mss::enable_read_ecc(p) );

            // At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.

            // Cram a fast write, followed by a read in here for giggles
            {
                mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
                uint64_t l_start = 0;
                uint64_t l_end = 0;
                uint64_t l_pattern = 0;

                // Write
                {
                    // Uses address register set 0
                    mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
                        mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
                    l_fw_subtest.enable_port(mss::pos(p));

                    // ECC mode off causes compares. Fixed mode data means it will
                    // compare to the data in the MCBFD#Q registers.
                    l_fw_subtest.change_ecc_mode(mss::OFF);

                    // HACK: We only need to worry about the DIMM in slot 0 right now
                    l_fw_subtest.enable_dimm(0);
                    l_program.iv_subtests.push_back(l_fw_subtest);
                }

                // Read
                {
                    // Uses address register set 0
                    mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
                        mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
                    l_fr_subtest.enable_port(mss::pos(p));

                    // ECC mode off causes compares. Fixed mode data means it will
                    // compare to the data in the MCBFD#Q registers.
                    l_fr_subtest.change_ecc_mode(mss::OFF);

                    // HACK: We only need to worry about the DIMM in slot 0 right now
                    l_fr_subtest.enable_dimm(0);
                    l_program.iv_subtests.push_back(l_fr_subtest);
                }

                FAPI_TRY( mss::mcbist_start_addr(p, l_start) );
                FAPI_TRY( mss::mcbist_end_addr(p, l_end) );

                // TK: calculate proper polling based on address range

                // Setup a nice pattern for writing
                FAPI_TRY( mss::mcbist_write_data(i_target, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD0Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD1Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD2Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD3Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD4Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD5Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD6Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD7Q, l_pattern) );

                // Sanity check - can't do much if end is before start.
                // This is either a programming error or a mistake in attribute settings. So we'll just assert.
                if (l_end < l_start)
                {
                    FAPI_ERR("mcbist end address is less than mcbist starting address. s: 0x%x e: 0x%x", l_start, l_end);
                    fapi2::Assert(false);
                }

                // By default we're in maint address mode so we do a start + len and the 'BIST increments for us.
                // By default, the write subtest uses the 0'th address start/end registers.
                mss::mcbist::config_address_range0(i_target, l_start, l_end - l_start);

                // Setup the polling based on a heuristic <cough>guess</cough>
                // Looks like 20ns per address for a write/read program, and add a long number of polls
                l_program.iv_poll.iv_initial_delay = (l_end - l_start) * 2 * mss::DELAY_10NS;
                l_program.iv_poll.iv_initial_sim_delay =
                    mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, l_program.iv_poll.iv_initial_delay));
                l_program.iv_poll.iv_poll_count = 100;

                // Just one port for now. Per Shelton we need to set this in maint adress mode
                // even tho we specify the port/dimm in the subtest.
                fapi2::buffer<uint8_t> l_port;
                l_port.setBit(mss::pos(p));
                l_program.select_ports(l_port >> 4);

                // Kick it off, wait for a result
                FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
            }
        }

    fapi_try_exit:
        FAPI_INF("End draminit MC");
        return fapi2::current_err;
    }
}
<commit_msg>Change draminit_mc to run ECC mode not compare mode<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C $         */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_mc.C
/// @brief Initialize the memory controller to take over the DRAM
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_draminit_mc.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;

extern "C"
{
///
/// @brief Initialize the MC now that DRAM is up
/// @param[in] i_target, the McBIST of the ports
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_mc( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        auto l_mca = i_target.getChildren<TARGET_TYPE_MCA>();

        FAPI_INF("Start draminit MC");

        // If we don't have any ports, lets go.
        if (l_mca.size() == 0)
        {
            FAPI_INF("No ports? %s", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        // While we're doing the scominit in here, lets do it for all ports before we dump the MCS regs.
        for (auto p : i_target.getChildren<TARGET_TYPE_MCA>())
        {
            mss::mc<TARGET_TYPE_MCS> l_mc;

            // Don't do this yet - leverage the sim inits for the moment
#if 0
            // All the scominit for this MCA
            l_mc.scominit(p);
#endif
            // Setup the MC port/dimm address translation registers
            FAPI_TRY( l_mc.setup_xlate_map(p) );
        }

        for (auto p : l_mca)
        {

            // Setup the read_pointer_delay
            // TK: Do we need to do this in general or is this a place holder until the
            // init file gets here?
            {
                fapi2::buffer<uint64_t> l_data;
                FAPI_TRY( mss::getScom(p, MCA_RECR, l_data) );
                l_data.insertFromRight<MCA_RECR_MBSECCQ_READ_POINTER_DELAY, MCA_RECR_MBSECCQ_READ_POINTER_DELAY_LEN>(0x1);
                FAPI_DBG("writing read pointer delay 0x%016lx %s", l_data, mss::c_str(p));
                FAPI_TRY( mss::putScom(p, MCA_RECR, l_data) );
            }

            // Set the IML Complete bit MBSSQ(3) (SCOM Addr: 0x02011417) to indicate that IML has completed
            // Can't find MBSSQ or the iml_complete bit - asked Steve. Gary VH created this bit as a scratch
            // 'you are hre bit' and it was removed for Nimbus. Gary VH asked for it to be put back in. Not
            // sure if that happened yet. BRS (2/16).

            // Reset addr_mux_sel to “0” to allow the MCA to take control of the DDR interface over from CCS.
            // (Note: this step must remain in this procedure to ensure that data path is placed into mainline
            // mode prior to running memory diagnostics. This step maybe superfluous but not harmful.)
            // Note: addr_mux_sel is set low in p9_mss_draminit(), however that might be a work-around so we
            // set it low here kind of like belt-and-suspenders. BRS
            FAPI_TRY( mss::change_addr_mux_sel(p, mss::LOW) );

            // Re-enable port fails. Turned off in draminit_training
            FAPI_TRY( mss::change_port_fail_disable(p, mss::OFF ) );

            // Step Two.1: Check RCD protect time on RDIMM and LRDIMM
            // Step Two.2: Enable address inversion on each MBA for ALL CARDS

            // Start the refresh engines by setting MBAREF0Q(0) = “1”. Note that the remaining bits in
            // MBAREF0Q should retain their initialization values.
            FAPI_TRY( mss::change_refresh_enable(p, mss::HIGH) );

            // Power management is handled in the init file. (or should be BRS)

            // Enabling periodic calibration
            FAPI_TRY( mss::enable_periodic_cal(p) );

            // Step Six: Setup Control Bit ECC
            FAPI_TRY( mss::enable_read_ecc(p) );

            // At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.

            // Cram a fast write, followed by a read in here for giggles
            {
                mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
                uint64_t l_start = 0;
                uint64_t l_end = 0;
                uint64_t l_pattern = 0;

                // Write
                {
                    // Uses address register set 0
                    mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
                        mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
                    l_fw_subtest.enable_port(mss::pos(p));

                    // Run in ECC mode

                    // HACK: We only need to worry about the DIMM in slot 0 right now
                    l_fw_subtest.enable_dimm(0);
                    l_program.iv_subtests.push_back(l_fw_subtest);
                }

                // Read
                {
                    // Uses address register set 0
                    mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
                        mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
                    l_fr_subtest.enable_port(mss::pos(p));

                    // Run in ECC mode

                    // HACK: We only need to worry about the DIMM in slot 0 right now
                    l_fr_subtest.enable_dimm(0);
                    l_program.iv_subtests.push_back(l_fr_subtest);
                }

                FAPI_TRY( mss::mcbist_start_addr(p, l_start) );
                FAPI_TRY( mss::mcbist_end_addr(p, l_end) );

                // TK: calculate proper polling based on address range

                // Setup a nice pattern for writing
                FAPI_TRY( mss::mcbist_write_data(i_target, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD0Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD1Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD2Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD3Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD4Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD5Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD6Q, l_pattern) );
                FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD7Q, l_pattern) );

                // Sanity check - can't do much if end is before start.
                // This is either a programming error or a mistake in attribute settings. So we'll just assert.
                if (l_end < l_start)
                {
                    FAPI_ERR("mcbist end address is less than mcbist starting address. s: 0x%x e: 0x%x", l_start, l_end);
                    fapi2::Assert(false);
                }

                // By default we're in maint address mode so we do a start + len and the 'BIST increments for us.
                // By default, the write subtest uses the 0'th address start/end registers.
                mss::mcbist::config_address_range0(i_target, l_start, l_end - l_start);

                // Setup the polling based on a heuristic <cough>guess</cough>
                // Looks like 20ns per address for a write/read program, and add a long number of polls
                l_program.iv_poll.iv_initial_delay = (l_end - l_start) * 2 * mss::DELAY_10NS;
                l_program.iv_poll.iv_initial_sim_delay =
                    mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, l_program.iv_poll.iv_initial_delay));
                l_program.iv_poll.iv_poll_count = 100;

                // Just one port for now. Per Shelton we need to set this in maint adress mode
                // even tho we specify the port/dimm in the subtest.
                fapi2::buffer<uint8_t> l_port;
                l_port.setBit(mss::pos(p));
                l_program.select_ports(l_port >> 4);

                // Kick it off, wait for a result
                FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
            }
        }

    fapi_try_exit:
        FAPI_INF("End draminit MC");
        return fapi2::current_err;
    }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_sbe_hb_structures.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//------------------------------------------------------------------------------------
//
/// @file p9_sbe_hb_structures.H
/// @brief Structures that the SBE and HB will both use
//
// *HWP HWP Owner: Christina Graves clgraves@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: SBE, HB
//-----------------------------------------------------------------------------------

#ifndef _SBE_HB_STRUCTURES_H_
#define _SBE_HB_STRUCTURES_H_

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------------

// Structure starts at the bootloader zero address
struct BootloaderConfigData_t
{
    uint32_t version;  // Some kind of version field so we know if there is new data being added
    uint8_t sbeBootSide;  // 0=SBE side 0, 1=SBE side 1   [ATTR_SBE_BOOT_SIDE]
    uint8_t pnorBootSide;  // 0=PNOR side A, 1=PNOR side B  [ATTR_PNOR_BOOT_SIDE]
    uint16_t pnorSizeMB;  // Size of PNOR in MB  [ATTR_PNOR_SIZE]
    uint64_t blLoadSize;  // Size of Load (Exception vectors and Bootloader)
};

#endif
<commit_msg>Add Secure Access Bit to Bootloader Config Data<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_sbe_hb_structures.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//------------------------------------------------------------------------------------
//
/// @file p9_sbe_hb_structures.H
/// @brief Structures that the SBE and HB will both use
//
// *HWP HWP Owner: Christina Graves clgraves@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: SBE, HB
//-----------------------------------------------------------------------------------

#ifndef _SBE_HB_STRUCTURES_H_
#define _SBE_HB_STRUCTURES_H_

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------------

// Used for version checking as the BootloaderConfigData_t structure changes
enum SbeBootloaderVersion
{
    // Keep initial version formatted as it was originally
    INIT = 0x901,
    // Later versions use format [release:2][version:2]
    SAB_ADDED = 0x00090002
};

// Structure starts at the bootloader zero address
struct BootloaderConfigData_t
{
    uint32_t version;  // Some kind of version field so we know if there is new data being added
    uint8_t sbeBootSide;  // 0=SBE side 0, 1=SBE side 1   [ATTR_SBE_BOOT_SIDE]
    uint8_t pnorBootSide;  // 0=PNOR side A, 1=PNOR side B  [ATTR_PNOR_BOOT_SIDE]
    uint16_t pnorSizeMB;  // Size of PNOR in MB  [ATTR_PNOR_SIZE]
    uint64_t blLoadSize;  // Size of Load (Exception vectors and Bootloader)
    uint8_t secureAccessBit;
};

#endif
<|endoftext|>


<commit_before>#include "finite_automaton.h"

#include <algorithm>
#include <unordered_set>
#include <iostream>

const std::vector<FiniteAutomaton::symbol_type> & FiniteAutomaton::alphabet() const
{
	if (_alphabet.empty())
	{
		std::unordered_set<symbol_type> symbolset;
		for (std::size_t i = 0; i < states.size(); ++i)
		{
			for (const auto& p : states[i]->transitions())
			{
				if (!p.symbol().is_epsilon()) symbolset.insert(p.symbol());
			}
		}
		_alphabet.assign(symbolset.begin(), symbolset.end());
	}
	return _alphabet;
}

int FiniteAutomaton::transition(int state_id, const symbol_type & symbol) const
{
	auto it = std::find_if(states[state_id]->transitions().begin(),
	                       states[state_id]->transitions().end(),
	                       [symbol](auto trans)
	                       { return trans.symbol() == symbol; });

	return it == states[state_id]->transitions().end() ?
		-1 :
		it->state()->state_id();
}

void FiniteAutomaton::print() const
{
	for (std::size_t i = 0; i < states.size(); ++i)
	{
		auto p = states[i].get();
		for (const auto& trans : p->transitions())
		{
			std::cout << "from state #" << p->state_id()
			          << " through: " << (trans.symbol().is_epsilon() ? "epsilon" : trans.symbol().to_string())
			          << " to state #" << trans.state()->state_id()
			          << '\n';
		}
		std::cout << "--------------\n\n";
	}
}

void FiniteAutomaton::set_states_ids()
{
	for (std::size_t i = 0; i < states.size(); ++i)
	{
		states[i]->_state_id = i;
	}
}
<commit_msg>Print accept states in FiniteAutomaton::print()<commit_after>#include "finite_automaton.h"

#include <algorithm>
#include <unordered_set>
#include <iostream>

const std::vector<FiniteAutomaton::symbol_type> & FiniteAutomaton::alphabet() const
{
	if (_alphabet.empty())
	{
		std::unordered_set<symbol_type> symbolset;
		for (std::size_t i = 0; i < states.size(); ++i)
		{
			for (const auto& p : states[i]->transitions())
			{
				if (!p.symbol().is_epsilon()) symbolset.insert(p.symbol());
			}
		}
		_alphabet.assign(symbolset.begin(), symbolset.end());
	}
	return _alphabet;
}

int FiniteAutomaton::transition(int state_id, const symbol_type & symbol) const
{
	auto it = std::find_if(states[state_id]->transitions().begin(),
	                       states[state_id]->transitions().end(),
	                       [symbol](auto trans)
	                       { return trans.symbol() == symbol; });

	return it == states[state_id]->transitions().end() ?
		-1 :
		it->state()->state_id();
}

void FiniteAutomaton::print() const
{
	std::cout << "Accept states: ";
	for (auto accept_state : accept_states)
	{
		std::cout << accept_state.state->state_id() << ' ';
	}
	std::cout << '\n';
	for (std::size_t i = 0; i < states.size(); ++i)
	{
		auto p = states[i].get();
		for (const auto& trans : p->transitions())
		{
			std::cout << "from state #" << p->state_id()
			          << " through: " << (trans.symbol().is_epsilon() ? "epsilon" : trans.symbol().to_string())
			          << " to state #" << trans.state()->state_id()
			          << '\n';
		}
		std::cout << "--------------\n\n";
	}
}

void FiniteAutomaton::set_states_ids()
{
	for (std::size_t i = 0; i < states.size(); ++i)
	{
		states[i]->_state_id = i;
	}
}
<|endoftext|>


<commit_before>/*
 * File:   Sphere.cpp
 * Author: Benedikt Vogler
 *
 * Created on 4. Juli 2014, 19:25
 */

#include "Sphere.hpp"

std::pair<bool, glm::vec3> Sphere::intersect(Ray const& ray) const {
    float b = 2 *(glm::dot(ray.origin,ray.direction));
    float c = glm::dot(ray.origin,ray.origin) - radius*radius;

    int root = b*b-4*c;
    if (root>0) {//wenn es min. eine Lösung gibt
        float t1 = -b-sqrt(root);
        float t2 = -b+sqrt(root);

        if (t1 < t2)//nimm Punkt, welcher näher dran ist
            return std::make_pair(true, ray.origin+ray.direction*t1);//use t1
        else
            return std::make_pair(true, ray.origin+ray.direction*t2);//use t2
    } else
        return std::make_pair(false, ray.origin);//keine Lösung
}

<commit_msg>Fixes sphere collission<commit_after>/*
 * File:   Sphere.cpp
 * Author: Benedikt Vogler
 *
 * Created on 4. Juli 2014, 19:25
 */

#include "Sphere.hpp"

std::pair<bool, glm::vec3> Sphere::intersect(Ray const& ray) const {
    glm::vec3 l = ray.origin - center;
    float a = glm::dot(ray.direction, ray.direction);
    float b = 2.0f*(glm::dot(l,ray.direction));
    float c = glm::dot(l,l) - radius*radius;

    float det = b*b-4.0f*a*c;
    if (det>=0.0f) {//wenn es min. eine Lösung gibt
        float t1 = (-b-sqrt(det))/(2.0f*a);
        float t2 = (-b+sqrt(det))/(2.0f*a);

        if (t1 < t2)//nimm Punkt, welcher näher dran ist
            return std::make_pair(true, l-(ray.origin+ray.direction*t1));//use t1
        else
            return std::make_pair(true, l-(ray.origin+ray.direction*t2));//use t2
    } else
        return std::make_pair(false, ray.origin);//keine Lösung
}<|endoftext|>


<commit_before>//
//
//    The Laxkit, a windowing toolkit
//    Please consult http://laxkit.sourceforge.net about where to send any
//    correspondence about this software.
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License as published by the Free Software Foundation; either
//    version 2 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Library General Public License for more details.
//
//    You should have received a copy of the GNU Library General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//    Copyright (C) 2004-2010,2014 by Tom Lechner
//

#include <lax/numslider.h>
#include <lax/laxutils.h>
#include <lax/strmanip.h>
#include <lax/lineedit.h>

#include <iostream>
using namespace std;

namespace Laxkit {

/*! \class NumSlider
 * \brief A slider control specifically for selecting integer numbers within a range.
 *
 * The range is [min,max]. If NUMSLIDER_WRAP is part of win_style, then sliding through
 * numbers wraps around, rather than stops at min or max.
 *
 * \todo  optional label:   [ Blah: 34 ]
 * \todo super shift/ shift-but4 to move faster*** put that in itemslider
 */

NumSlider::NumSlider(anXWindow *parnt,const char *nname,const char *ntitle,unsigned long nstyle,
		int xx,int yy,int ww,int hh,int brder,
		anXWindow *prev,unsigned long nowner,const char *nsendthis,const char *nlabel,int nmin,int nmax,int cur)
	: ItemSlider(parnt,nname,ntitle,nstyle,xx,yy,ww,hh,brder,prev,nowner,nsendthis)
{
	mode=0;
	nitems=0;

	min=nmin;
	max=nmax;
	step=1;

	curnum=cur;
	if (!(win_style&NO_MINIMUM) && curnum<min) curnum=min;
	else if (!(win_style&NO_MAXIMUM) && curnum>max) curnum=max;

	curitem=curnum;

	lastitem=-1;
	movewidth=2;
	label=NULL;
	labelbase=NULL;
	makestr(label,nlabel);

	installColors(app->color_panel);

	if (win_w==0 || win_h==0) wraptoextent();
}

NumSlider::NumSlider(anXWindow *parnt,const char *nname,const char *ntitle,unsigned long nstyle,
		int xx,int yy,int ww,int hh,int brder,
		anXWindow *prev,unsigned long nowner,const char *nsendthis,const char *nlabel,double nmin,double nmax,double cur, double nstep)
	: ItemSlider(parnt,nname,ntitle,nstyle,xx,yy,ww,hh,brder,prev,nowner,nsendthis)
{
	mode=0;
	nitems=0;

	win_style|=DOUBLES;
	min=nmin;
	max=nmax;
	step=nstep;

	curnum=cur;
	if (!(win_style&NO_MINIMUM) && curnum<min) curnum=min;
	else if (!(win_style&NO_MAXIMUM) && curnum>max) curnum=max;

	curitem=curnum;

	lastitem=-1;
	movewidth=2;
	label=NULL;
	labelbase=NULL;
	makestr(label,nlabel);

	installColors(app->color_panel);

	if (win_w==0 || win_h==0) wraptoextent();
}

NumSlider::~NumSlider()
{
	delete[] label;
	delete[] labelbase;
}

/*! Use a printf style format string to create label from integer curitem and nlabelbase.
 * nlabelbase MUST have a signed integer format in it (such as "%d"), unless
 * you are using DOUBLES style, in which case, it MUST have a double capable formatter,
 * such as "%f" or "%g".
 *
 * nlabelbase==NULL means use label as normal, and delete the labelbase.
 */
const char *NumSlider::LabelBase(const char *nlabelbase)
{
	makestr(labelbase,nlabelbase);
	needtodraw=1;
	return labelbase;
}

//! Change the label. If nlabel==NULL, then remove the label. Returns label.
const char *NumSlider::Label(const char *nlabel)
{
	needtodraw=1;
	return makestr(label,nlabel);
}

//! Find the maximum extent of the items, and set win_w,win_h to them if they are 0.
void NumSlider::wraptoextent()
{
	char num[30+(label?strlen(label):0)];
	double x,y,x2,y2;

	if (label) sprintf(num,"%s%d ",label,(int)max); else sprintf(num,"%d ",(int)max);
	getextent(num,-1,&x,&y);
	if (label) sprintf(num,"%s%d ",label,(int)min); else sprintf(num,"%d ",(int)min);
	getextent(num,-1,&x2,&y2);

	if (x2>x) x=x2;
	if (y2>y) y=y2;
	if (win_w==0) win_w=x;
	if (win_h==0) win_h=y;
}

//int NumSlider::MouseMove(int x,int y,unsigned int state,const LaxMouse *d)
//{
//}

void NumSlider::Refresh()
{
	if (!win_on || !needtodraw) return;

	Displayer *dp=MakeCurrent();
	if (hover) {
		dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.07));
		dp->drawrectangle(0,0,win_w,win_h, 1);
	} else dp->ClearWindow();

	dp->font(app->defaultlaxfont);

	 //draw arrows
	int ww=win_w/2;
	int hh=win_h/2;
	if (win_style&EDITABLE) ww=text_height();

	 // draw left arrow
	dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.2));
	dp->drawthing(hh/2,win_h/2, hh/2,hh/2, hover==LAX_LEFT?1:0, THING_Triangle_Left);

	 // draw right arrow
	dp->drawthing(win_w-hh/2,win_h/2, hh/2,hh/2, hover==LAX_RIGHT?1:0, THING_Triangle_Right);

	 //draw number
	if (hover==LAX_CENTER) {
		dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.2));
		hh=text_height()*1.1;
		dp->drawrectangle(ww,win_h/2-hh/2,win_w-2*ww,hh, 1);
	}

	dp->NewFG(win_colors->fg);
	char num[31+((labelbase?labelbase:label)?strlen((labelbase?labelbase:label)):0)];
	if (labelbase) sprintf(num,labelbase,curnum);
	else {
		if (win_style&DOUBLES) {
			if (label) sprintf(num,"%s %g",label,curnum);
			else sprintf(num,"%g",curnum);
		} else {
			if (label) sprintf(num,"%s %d",label,int(curnum+.5));
			else sprintf(num,"%d",int(.5+curnum));
		}
	}

	dp->textout(win_w/2,win_h/2, num,-1, LAX_CENTER);
	needtodraw=0;
}

int NumSlider::SelectPrevious(double multiplier)
{
	curnum-=multiplier*step;
	if (!(win_style&DOUBLES)) curnum=int(curnum+.5);

	if (!(win_style&NO_MINIMUM) && curnum<min) {
		if (win_style&WRAP) curnum=max;
		else curnum=min;
	}

	curitem=curnum;

	if (win_style & SENDALL) send();
	needtodraw=1;
	return curitem;
}

int NumSlider::SelectNext(double multiplier)
{
	curnum+=multiplier*step;
	if (!(win_style&DOUBLES)) curnum=int(curnum+.5);

	if (!(win_style&NO_MAXIMUM) && curnum>max) {
		if (win_style&WRAP) curnum=min;
		else curnum=max;
	}

	curitem=curnum;

	if (win_style & SENDALL) send();
	needtodraw=1;
	return curitem;
}

//! Select number nn. Does nothing if out of bounds. Returns current number.
int NumSlider::Select(int nn)
{
	if (curitem==nn || nn<min || nn>max) return curitem;
	curnum=nn;
	curitem=curnum;

	needtodraw=1;
	if (win_style & SENDALL) send();
	return curitem;
}

//! Select number nn. Does nothing if out of bounds. Returns current number.
int NumSlider::Select(double nn)
{
	if (!(win_style&NO_MINIMUM) && nn<min) return curitem;
	else if (!(win_style&NO_MAXIMUM) && nn>max) return curitem;
	if (curnum==nn) return curitem;

	curnum=nn;
	curitem=nn;

	needtodraw=1;
	if (win_style & SENDALL) send();
	return curitem;
}

int NumSlider::Mode(int newmode)
{
	if (newmode==1 && mode!=1) {
		 //edit current number
		char num[30];
		if ((win_style&DOUBLES)) sprintf(num,"%.8g",curnum);
		else sprintf(num,"%d",(int)curnum);

		LineEdit *le=new LineEdit(this,"inputedit",NULL,
			 LINEEDIT_DESTROY_ON_ENTER|((win_style&DOUBLES) ? LINEEDIT_FLOAT : LINEEDIT_INT),
			 0,0, win_w-4,win_h-4,2,
			 NULL,object_id,"lineedit",
			 num,0);

		le->SetSelection(0,-1);
		le->padx=5;
		app->addwindow(le);
		if (!le->xlib_window) return 0;
		app->setfocus(le,0,NULL);//***

		return 1;

	} else {
		mode=0;
		anXWindow *w=findChildWindowByName("inputedit");
		if (w) app->destroywindow(w);
	}

	needtodraw=1;
	return mode;
}

//! Catches when the lineedit receives enter..
int NumSlider::Event(const EventData *e,const char *mes)
{
	if (strcmp(mes,"lineedit")) return ItemSlider::Event(e,mes);

	const SimpleMessage *s=dynamic_cast<const SimpleMessage*>(e);
	if (!s) return ItemSlider::Event(e,mes);

	const char *blah=s->str;
	char *tmp;

	double ncurnum=strtod(blah,&tmp);
	if (!(win_style&DOUBLES)) ncurnum=int(ncurnum+.5);

	if (!(win_style&NO_MINIMUM) && ncurnum<min) ncurnum=min;
	else if (!(win_style&NO_MAXIMUM) && ncurnum>max) ncurnum=max;

	if (tmp!=blah) {
		curnum=ncurnum;
		curitem=ncurnum;
		needtodraw=1;
		send();
	}
	//app->destroywindow(le);

	return 0;
}

} // namespace Laxkit

<commit_msg>Added missing ANXWIN_OUT_CLICK_DESTROYS<commit_after>//
//
//    The Laxkit, a windowing toolkit
//    Please consult http://laxkit.sourceforge.net about where to send any
//    correspondence about this software.
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License as published by the Free Software Foundation; either
//    version 2 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Library General Public License for more details.
//
//    You should have received a copy of the GNU Library General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//    Copyright (C) 2004-2010,2014 by Tom Lechner
//

#include <lax/numslider.h>
#include <lax/laxutils.h>
#include <lax/strmanip.h>
#include <lax/lineedit.h>

#include <iostream>
using namespace std;

namespace Laxkit {

/*! \class NumSlider
 * \brief A slider control specifically for selecting integer numbers within a range.
 *
 * The range is [min,max]. If NUMSLIDER_WRAP is part of win_style, then sliding through
 * numbers wraps around, rather than stops at min or max.
 *
 * \todo  optional label:   [ Blah: 34 ]
 * \todo super shift/ shift-but4 to move faster*** put that in itemslider
 */

NumSlider::NumSlider(anXWindow *parnt,const char *nname,const char *ntitle,unsigned long nstyle,
		int xx,int yy,int ww,int hh,int brder,
		anXWindow *prev,unsigned long nowner,const char *nsendthis,const char *nlabel,int nmin,int nmax,int cur)
	: ItemSlider(parnt,nname,ntitle,nstyle,xx,yy,ww,hh,brder,prev,nowner,nsendthis)
{
	mode=0;
	nitems=0;

	min=nmin;
	max=nmax;
	step=1;

	curnum=cur;
	if (!(win_style&NO_MINIMUM) && curnum<min) curnum=min;
	else if (!(win_style&NO_MAXIMUM) && curnum>max) curnum=max;

	curitem=curnum;

	lastitem=-1;
	movewidth=2;
	label=NULL;
	labelbase=NULL;
	makestr(label,nlabel);

	installColors(app->color_panel);

	if (win_w==0 || win_h==0) wraptoextent();
}

NumSlider::NumSlider(anXWindow *parnt,const char *nname,const char *ntitle,unsigned long nstyle,
		int xx,int yy,int ww,int hh,int brder,
		anXWindow *prev,unsigned long nowner,const char *nsendthis,const char *nlabel,double nmin,double nmax,double cur, double nstep)
	: ItemSlider(parnt,nname,ntitle,nstyle,xx,yy,ww,hh,brder,prev,nowner,nsendthis)
{
	mode=0;
	nitems=0;

	win_style|=DOUBLES;
	min=nmin;
	max=nmax;
	step=nstep;

	curnum=cur;
	if (!(win_style&NO_MINIMUM) && curnum<min) curnum=min;
	else if (!(win_style&NO_MAXIMUM) && curnum>max) curnum=max;

	curitem=curnum;

	lastitem=-1;
	movewidth=2;
	label=NULL;
	labelbase=NULL;
	makestr(label,nlabel);

	installColors(app->color_panel);

	if (win_w==0 || win_h==0) wraptoextent();
}

NumSlider::~NumSlider()
{
	delete[] label;
	delete[] labelbase;
}

/*! Use a printf style format string to create label from integer curitem and nlabelbase.
 * nlabelbase MUST have a signed integer format in it (such as "%d"), unless
 * you are using DOUBLES style, in which case, it MUST have a double capable formatter,
 * such as "%f" or "%g".
 *
 * nlabelbase==NULL means use label as normal, and delete the labelbase.
 */
const char *NumSlider::LabelBase(const char *nlabelbase)
{
	makestr(labelbase,nlabelbase);
	needtodraw=1;
	return labelbase;
}

//! Change the label. If nlabel==NULL, then remove the label. Returns label.
const char *NumSlider::Label(const char *nlabel)
{
	needtodraw=1;
	return makestr(label,nlabel);
}

//! Find the maximum extent of the items, and set win_w,win_h to them if they are 0.
void NumSlider::wraptoextent()
{
	char num[30+(label?strlen(label):0)];
	double x,y,x2,y2;

	if (label) sprintf(num,"%s%d ",label,(int)max); else sprintf(num,"%d ",(int)max);
	getextent(num,-1,&x,&y);
	if (label) sprintf(num,"%s%d ",label,(int)min); else sprintf(num,"%d ",(int)min);
	getextent(num,-1,&x2,&y2);

	if (x2>x) x=x2;
	if (y2>y) y=y2;
	if (win_w==0) win_w=x;
	if (win_h==0) win_h=y;
}

//int NumSlider::MouseMove(int x,int y,unsigned int state,const LaxMouse *d)
//{
//}

void NumSlider::Refresh()
{
	if (!win_on || !needtodraw) return;

	Displayer *dp=MakeCurrent();
	if (hover) {
		dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.07));
		dp->drawrectangle(0,0,win_w,win_h, 1);
	} else dp->ClearWindow();

	dp->font(app->defaultlaxfont);

	 //draw arrows
	int ww=win_w/2;
	int hh=win_h/2;
	if (win_style&EDITABLE) ww=text_height();

	 // draw left arrow
	dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.2));
	dp->drawthing(hh/2,win_h/2, hh/2,hh/2, hover==LAX_LEFT?1:0, THING_Triangle_Left);

	 // draw right arrow
	dp->drawthing(win_w-hh/2,win_h/2, hh/2,hh/2, hover==LAX_RIGHT?1:0, THING_Triangle_Right);

	 //draw number
	if (hover==LAX_CENTER) {
		dp->NewFG(coloravg(win_colors->bg,win_colors->fg,.2));
		hh=text_height()*1.1;
		dp->drawrectangle(ww,win_h/2-hh/2,win_w-2*ww,hh, 1);
	}

	dp->NewFG(win_colors->fg);
	char num[31+((labelbase?labelbase:label)?strlen((labelbase?labelbase:label)):0)];
	if (labelbase) sprintf(num,labelbase,curnum);
	else {
		if (win_style&DOUBLES) {
			if (label) sprintf(num,"%s %g",label,curnum);
			else sprintf(num,"%g",curnum);
		} else {
			if (label) sprintf(num,"%s %d",label,int(curnum+.5));
			else sprintf(num,"%d",int(.5+curnum));
		}
	}

	dp->textout(win_w/2,win_h/2, num,-1, LAX_CENTER);
	needtodraw=0;
}

int NumSlider::SelectPrevious(double multiplier)
{
	curnum-=multiplier*step;
	if (!(win_style&DOUBLES)) curnum=int(curnum+.5);

	if (!(win_style&NO_MINIMUM) && curnum<min) {
		if (win_style&WRAP) curnum=max;
		else curnum=min;
	}

	curitem=curnum;

	if (win_style & SENDALL) send();
	needtodraw=1;
	return curitem;
}

int NumSlider::SelectNext(double multiplier)
{
	curnum+=multiplier*step;
	if (!(win_style&DOUBLES)) curnum=int(curnum+.5);

	if (!(win_style&NO_MAXIMUM) && curnum>max) {
		if (win_style&WRAP) curnum=min;
		else curnum=max;
	}

	curitem=curnum;

	if (win_style & SENDALL) send();
	needtodraw=1;
	return curitem;
}

//! Select number nn. Does nothing if out of bounds. Returns current number.
int NumSlider::Select(int nn)
{
	if (curitem==nn || nn<min || nn>max) return curitem;
	curnum=nn;
	curitem=curnum;

	needtodraw=1;
	if (win_style & SENDALL) send();
	return curitem;
}

//! Select number nn. Does nothing if out of bounds. Returns current number.
int NumSlider::Select(double nn)
{
	if (!(win_style&NO_MINIMUM) && nn<min) return curitem;
	else if (!(win_style&NO_MAXIMUM) && nn>max) return curitem;
	if (curnum==nn) return curitem;

	curnum=nn;
	curitem=nn;

	needtodraw=1;
	if (win_style & SENDALL) send();
	return curitem;
}

int NumSlider::Mode(int newmode)
{
	if (newmode==1 && mode!=1) {
		 //edit current number
		char num[30];
		if ((win_style&DOUBLES)) sprintf(num,"%.8g",curnum);
		else sprintf(num,"%d",(int)curnum);

		LineEdit *le=new LineEdit(this,"inputedit",NULL,
			 ANXWIN_OUT_CLICK_DESTROYS|LINEEDIT_DESTROY_ON_ENTER|((win_style&DOUBLES) ? LINEEDIT_FLOAT : LINEEDIT_INT),
			 0,0, win_w-4,win_h-4,2,
			 NULL,object_id,"lineedit",
			 num,0);

		le->SetSelection(0,-1);
		le->padx=5;
		app->addwindow(le);
		if (!le->xlib_window) return 0;
		app->setfocus(le,0,NULL);//***

		return 1;

	} else {
		mode=0;
		anXWindow *w=findChildWindowByName("inputedit");
		if (w) app->destroywindow(w);
	}

	needtodraw=1;
	return mode;
}

//! Catches when the lineedit receives enter..
int NumSlider::Event(const EventData *e,const char *mes)
{
	if (strcmp(mes,"lineedit")) return ItemSlider::Event(e,mes);

	const SimpleMessage *s=dynamic_cast<const SimpleMessage*>(e);
	if (!s) return ItemSlider::Event(e,mes);

	const char *blah=s->str;
	char *tmp;

	double ncurnum=strtod(blah,&tmp);
	if (!(win_style&DOUBLES)) ncurnum=int(ncurnum+.5);

	if (!(win_style&NO_MINIMUM) && ncurnum<min) ncurnum=min;
	else if (!(win_style&NO_MAXIMUM) && ncurnum>max) ncurnum=max;

	if (tmp!=blah) {
		curnum=ncurnum;
		curitem=ncurnum;
		needtodraw=1;
		send();
	}
	//app->destroywindow(le);

	return 0;
}

} // namespace Laxkit

<|endoftext|>


<commit_before>//functor_overload header
//Copyright (c) 2014 mmYYmmdd

#if !defined MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED
#define MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED

#include <type_traits>
#include <utility>

namespace mymd {

	namespace detail_fol	{

		template <typename>
		struct noCondition	{
			static constexpr bool value = true;
		};

		template <template <typename> class C = noCondition, bool B = true>
		struct cond	{ };
		//-----------------------------------------------------
		template <typename...> struct packeR { };
		//-----------------------------------------------------
		template <typename T, typename>
		struct arg  {
			using apply  = std::enable_if<true, T>;
			using applyr = apply;
		};

		template <template <typename> class C, bool B, typename V>
		struct arg<cond<C, B>, V>  {
			using apply  = std::enable_if<B == C<V>::value, V>;
			using applyr = std::enable_if<B == C<V>::value, V&&>;
		};
		//-----------------------------------------------------
		struct no_action	{
			constexpr no_action() { }
			template <typename... V>
			void operator ()(V&&...) const {}
		};
		//-----------------------------------------------------
		template <typename F, typename... A>
		class bolt  {
			F fn;
			template <typename T, typename U>
			using apply = typename arg<T, U>::apply::type;	//workaround for VC
		protected:
			template <typename... V>
			auto invoke(packeR<V...>, typename arg<A, V>::applyr::type... a) const
				->decltype(fn(std::declval<apply<A, V>>()...))
				{  return fn(std::forward<apply<A, V>>(a) ...);  }
			template <typename... V>
			auto invoke(packeR<V...>, typename arg<A, V>::applyr::type... a)
				->decltype(fn(std::declval<apply<A, V>>()...))
				{  return fn(std::forward<apply<A, V>>(a) ...);  }
		public:
			constexpr bolt(const F& f) : fn(f)  {  }
		};
		//-----------------------------------------------------
		template <typename T1, typename T2>
		class bolts : private T1, private T2  {
			protected: using T1::invoke; using T2::invoke;
		public:
			constexpr bolts(const T1& t1, const T2& t2) : T1(t1), T2(t2) { }
			template <typename... V>
			auto operator()(V&&... v) const->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
				{  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
			template <typename... V>
			auto operator()(V&&... v) ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
				{  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
		};

		template <typename F, typename... A>
		class bolts<bolt<F, A...>, void> : private bolt<F, A...>  {
			protected : using bolt<F, A...>::invoke;
		public:
			constexpr bolts(const F& t) : bolt<F, A...>(t) { }
			template <typename... V>
			auto operator()(V&&... v) const->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
				{  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
			template <typename... V>
			auto operator()(V&&... v) ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
				{  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
		};

		template <typename T1, typename T2, typename U1, typename U2>
		auto operator +(bolts<T1, T2> const& b, bolts<U1, U2> const& c) ->bolts<bolts<T1, T2>, bolts<U1, U2>>
		{
			return bolts<bolts<T1, T2>, bolts<U1, U2>>(b, c);
		}
		//-----------------------------------------------------
		template <typename F, typename... A>
		using gen_t = bolts<bolt<typename std::conditional<std::is_same<F, void>::value, no_action, F>::type, A...>, void>;

	}	//namespace detail_fol
	//********************************************************************
	//  user interfaces are ,
	//  mymd::gen<A, B, C...>(Fn)  ,  mymd::cond<P>  ,  operator +
	//********************************************************************
	using detail_fol::cond;		//  condition for type
	using detail_fol::bolts;		//  functor type
	using detail_fol::gen_t;		//  functor type generated by 'gen'

	template <typename... A, typename F>
	auto gen(const F& f) ->gen_t<F, A...>
	{	return gen_t<F, A...>(f);	}

	//no action
	template <typename... A>
	auto gen() ->gen_t<void, A...>
	{	return gen_t<void, A...>(detail_fol::no_action{});	}

}	//namespace mymd

#endif

/*
#if defined MMYYMMDD_MBIND_INCLUDED
namespace mymd {
	namespace detail_fol	{
		template <template <typename...> class M, typename... binder, typename V>
		struct arg<mymd::mbind<M, binder...>, V>  {
			using mb = typename mymd::mbind<M, binder...>::template apply<V>;
			using apply  = std::enable_if<mb::value, V>;
			using applyr = std::enable_if<mb::value, V&&>;
		};
	}
}
#endif
*/
<commit_msg>gen が関数への参照型も取れるように修正<commit_after>//functor_overload header
//Copyright (c) 2014 mmYYmmdd

#if !defined MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED
#define MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED

#include <type_traits>
#include <utility>

namespace mymd {

    namespace detail_fol    {

        template <typename>
        struct noCondition  {
            static const bool value     =       true;
        };

        template <template <typename> class C = noCondition,    bool B = true>
        struct cond	{ };
        //-----------------------------------------------------
        template <typename...> struct packeR { };
        //-----------------------------------------------------
        template <typename T, typename>
        struct arg  {
            using apply     =   std::enable_if<true, T>;
            using applyr    =   apply;
        };

        template <template <typename> class C,      bool B,     typename V>
        struct arg<cond<C, B>, V>  {
            using apply     =   std::enable_if< B == C<V>::value, V   >;
            using applyr    =   std::enable_if< B == C<V>::value, V&& >;
        };
        //-----------------------------------------------------
        struct no_action    {
            constexpr no_action() { }
            template <typename... V>
            void operator ()(V&&...) const {}
        };
        //-----------------------------------------------------
        template <typename F,   typename... A>
        class bolt  {
            F       fn;
            template <typename T, typename U>
            using apply     =    typename arg<T, U>::apply::type;  //workaround for VC
        protected:
            template <typename... V>
            auto invoke(packeR<V...>, typename arg<A, V>::applyr::type... a) const
                ->decltype(fn(std::declval<apply<A, V>>()...))
            { return fn(std::forward<apply<A, V>>(a) ...); }
            template <typename... V>
            auto invoke(packeR<V...>, typename arg<A, V>::applyr::type... a)
                ->decltype(fn(std::declval<apply<A, V>>()...))
            { return fn(std::forward<apply<A, V>>(a) ...); }
        public:
            constexpr bolt(const F& f) : fn(f)  {  }
        };
        //-----------------------------------------------------
        template <  typename T1,    typename T2 >
        class bolts :   private T1,     private T2  {
            protected:      using T1::invoke;    using T2::invoke;
        public:
            constexpr bolts(const T1& t1, const T2& t2) :   T1(t1),     T2(t2) { }
            template <typename... V>
            auto operator()(V&&... v) const     ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
            {  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
            template <typename... V>
            auto operator()(V&&... v)           ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
            {  return invoke(packeR<V...>{}, std::forward<V>(v)...);  }
        };

        template <typename F,   typename... A>
        class bolts<bolt<F, A...>, void> :      private bolt<F, A...>  {
            protected :     using bolt<F, A...>::invoke;
        public:
            constexpr bolts(const F& t) : bolt<F, A...>(t) { }
            template <typename... V>
            auto operator()(V&&... v) const     ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
            { return invoke(packeR<V...>{}, std::forward<V>(v)...); }
            template <typename... V>
            auto operator()(V&&... v)           ->decltype(invoke(packeR<V...>{}, std::declval<V>()...))
            { return invoke(packeR<V...>{}, std::forward<V>(v)...); }
        };

        template <typename T1, typename T2,     typename U1, typename U2>
        auto operator + (   bolts<T1, T2> const& b,    bolts<U1, U2> const& c   )    ->bolts<bolts<T1, T2>, bolts<U1, U2>>
        { return bolts<bolts<T1, T2>, bolts<U1, U2>>(b, c); }
        //-----------------------------------------------------
        template <typename F, typename... A>
        using gen_t = bolts<bolt<typename std::conditional<std::is_same<F, void>::value, no_action, F>::type, A...>, void>;

    }   //namespace detail_fol
    //********************************************************************
    //  user interfaces are ,
    //  mymd::gen<A, B, C...>(Fn)  ,  mymd::cond<P>  ,  operator +
    //********************************************************************
    using   detail_fol::cond;         //  condition for type
    using   detail_fol::bolts;        //  functor type
    using   detail_fol::gen_t;        //  functor type generated by 'gen'

    template <typename... A, typename F>
    auto gen(const F& f)    ->gen_t<typename std::decay<F>::type, A...>
    { return gen_t<typename std::decay<F>::type, A...>(f); }

    //no action
    template <typename... A>
    auto gen()      ->gen_t<void, A...>
    { return gen_t<void, A...>(detail_fol::no_action{}); }

}   //namespace mymd

#endif

/*
#if defined MMYYMMDD_MBIND_INCLUDED
namespace mymd {
    namespace detail_fol    {
        template <template <typename...> class M, typename... binder, typename V>
        struct arg<mymd::mbind<M, binder...>, V>  {
            using mb = typename mymd::mbind<M, binder...>::template apply<V>;
            using apply  = std::enable_if<mb::value, V>;
            using applyr = std::enable_if<mb::value, V&&>;
        };
    }
}
#endif
*/
<|endoftext|>