<commit_before>/*
 * Copyright 1999,2005 The Apache Software Foundation.
 *
 * 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.
 */
#define __STDC_CONSTANT_MACROS
#include <log4cxx/helpers/cacheddateformat.h>

#include <apr_time.h>
#include <log4cxx/helpers/pool.h>
#include <limits>
#include <log4cxx/helpers/exception.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::pattern;

/**
*  Supported digit set.  If the wrapped DateFormat uses
*  a different unit set, the millisecond pattern
*  will not be recognized and duplicate requests
*  will use the cache.
*/
const logchar* const CachedDateFormat::digits = LOG4CXX_STR("0123456789");

/**
 *  Expected representation of first magic number.
 */
const logchar* const CachedDateFormat::magicString1 = LOG4CXX_STR("654");

/**
 *  Expected representation of second magic number.
 */
const logchar* const CachedDateFormat::magicString2 = LOG4CXX_STR("987");

/**
 *  Expected representation of 0 milliseconds.
 */
const logchar* const CachedDateFormat::zeroString = LOG4CXX_STR("000");

#undef min

/**
 *  Creates a new CachedDateFormat object.
 *  @param dateFormat Date format, may not be null.
 *  @param expiration maximum cached range in milliseconds.
 *    If the dateFormat is known to be incompatible with the
 *      caching algorithm, use a value of 0 to totally disable
 *      caching or 1 to only use cache for duplicate requests.
 */
CachedDateFormat::CachedDateFormat(const DateFormatPtr& dateFormat,
        int expiration) :
       formatter(dateFormat),
       millisecondStart(0),
       slotBegin(std::numeric_limits<log4cxx_time_t>::min()),
       cache(50, LOG4CXX_STR(' ')),
       expiration(expiration),
       previousTime(std::numeric_limits<log4cxx_time_t>::min()) {
  if (dateFormat == NULL) {
    throw IllegalArgumentException("dateFormat cannot be null");
  }
  if (expiration < 0) {
    throw IllegalArgumentException("expiration must be non-negative");
  }
}

/**
 * Finds start of millisecond field in formatted time.
 * @param time long time, must be integral number of seconds
 * @param formatted String corresponding formatted string
 * @param formatter DateFormat date format
 * @return int position in string of first digit of milliseconds,
 *    -1 indicates no millisecond field, -2 indicates unrecognized
 *    field (likely RelativeTimeDateFormat)
 */
int CachedDateFormat::findMillisecondStart(
  apr_time_t time, const LogString& formatted,
  const DateFormatPtr& formatter,
  Pool& pool) {

  apr_time_t slotBegin = (time / 1000000) * 1000000;
  if (slotBegin > time) {
     slotBegin -= 1000000;
  }
  int millis = (int) (time - slotBegin)/1000;

  int magic = magic1;
  LogString magicString(magicString1);
  if (millis == magic1) {
      magic = magic2;
      magicString = magicString2;
  }

  LogString plusMagic;
  formatter->format(plusMagic, slotBegin + magic, pool);

  /**
   *   If the string lengths differ then
   *      we can't use the cache except for duplicate requests.
   */
  if (plusMagic.length() != formatted.length()) {
      return UNRECOGNIZED_MILLISECONDS;
  } else {
      // find first difference between values
     for (LogString::size_type i = 0; i < formatted.length(); i++) {
        if (formatted[i] != plusMagic[i]) {
           //
           //   determine the expected digits for the base time
           LogString formattedMillis(LOG4CXX_STR("ABC"));
           millisecondFormat(millis, formattedMillis, 0);

           LogString plusZero;
           formatter->format(plusZero, slotBegin, pool);

           //   If the next 3 characters match the magic
           //      strings and the remaining fragments are identical
           //
           //
           if (plusZero.length() == formatted.length()
              && regionMatches(magicString, 0, plusMagic, i, magicString.length())
              && regionMatches(formattedMillis, 0, formatted, i, magicString.length())
              && regionMatches(zeroString, 0, plusZero, i, 3)
              && (formatted.length() == i + 3
                 || plusZero.compare(i + 3,
                       LogString::npos, plusMagic, i+3, LogString::npos) == 0)) {
              return i;
           } else {
              return UNRECOGNIZED_MILLISECONDS;
          }
        }
     }
  }
  return  NO_MILLISECONDS;
}

/**
 * Formats a millisecond count into a date/time string.
 *
 *  @param now Number of milliseconds after midnight 1 Jan 1970 GMT.
 *  @param sbuf the string buffer to write to
 */
 void CachedDateFormat::format(LogString& buf, log4cxx_time_t now, Pool& p) const {

  //
  // If the current requested time is identical to the previously
  //     requested time, then append the cache contents.
  //
  if (now == previousTime) {
       buf.append(cache);
       return;
  }

  //
  //   If millisecond pattern was not unrecognized
  //     (that is if it was found or milliseconds did not appear)
  //
  if (millisecondStart != UNRECOGNIZED_MILLISECONDS) {

      //    Check if the cache is still valid.
      //    If the requested time is within the same integral second
      //       as the last request and a shorter expiration was not requested.
      if (now < slotBegin + expiration
          && now >= slotBegin
          && now < slotBegin + 1000000L) {

          //
          //    if there was a millisecond field then update it
          //
          if (millisecondStart >= 0 ) {
              millisecondFormat((int) ((now - slotBegin)/1000), cache, millisecondStart);
          }
          //
          //   update the previously requested time
          //      (the slot begin should be unchanged)
          previousTime = now;
          buf.append(cache);
          return;
      }
  }

  //
  //  could not use previous value.
  //    Call underlying formatter to format date.
  cache.erase(cache.begin(), cache.end());
  formatter->format(cache, now, p);
  buf.append(cache);
  previousTime = now;
  slotBegin = (previousTime / 1000000) * 1000000;
  if (slotBegin > previousTime) {
      slotBegin -= 1000000;
  }

  //
  //    if the milliseconds field was previous found
  //       then reevaluate in case it moved.
  //
  if (millisecondStart >= 0) {
      millisecondStart = findMillisecondStart(now, cache, formatter, p);
  }
}

/**
 *   Formats a count of milliseconds (0-999) into a numeric representation.
 *   @param millis Millisecond coun between 0 and 999.
 *   @buf String buffer, may not be null.
 *   @offset Starting position in buffer, the length of the
 *       buffer must be at least offset + 3.
 */
void CachedDateFormat::millisecondFormat(int millis,
     LogString& buf,
     int offset) {
     buf[offset] = digits[ millis / 100];
     buf[offset + 1] = digits[(millis / 10) % 10];
     buf[offset + 2] = digits[millis  % 10];
 }

/**
 * Set timezone.
 *
 * @remarks Setting the timezone using getCalendar().setTimeZone()
 * will likely cause caching to misbehave.
 * @param timeZone TimeZone new timezone
 */
void CachedDateFormat::setTimeZone(const TimeZonePtr& timeZone) {
  formatter->setTimeZone(timeZone);
  previousTime = std::numeric_limits<log4cxx_time_t>::min();
  slotBegin = std::numeric_limits<log4cxx_time_t>::min();
}

void CachedDateFormat::numberFormat(LogString& s, int n, Pool& p) const {
  formatter->numberFormat(s, n, p);
}

/**
 * Gets maximum cache validity for the specified SimpleDateTime
 *    conversion pattern.
 *  @param pattern conversion pattern, may not be null.
 *  @returns Duration in microseconds from an integral second
 *      that the cache will return consistent results.
 */
int CachedDateFormat::getMaximumCacheValidity(const LogString& pattern) {
   //
   //   If there are more "S" in the pattern than just one "SSS" then
   //      (for example, "HH:mm:ss,SSS SSS"), then set the expiration to
   //      one millisecond which should only perform duplicate request caching.
   //
   size_t firstS = pattern.find(LOG4CXX_STR('S'));
   size_t len = pattern.length();
   //
   //   if there are no S's or
   //      three that start with the first S and no fourth S in the string
   //
   if (firstS == LogString::npos ||
       (len >= firstS + 3 && pattern.compare(firstS, 3, LOG4CXX_STR("SSS")) == 0
           && (len == firstS + 3 ||
                pattern.find(LOG4CXX_STR('S'), firstS + 3) == LogString::npos))) {
           return 1000000;
   }
   return 1000;
}

/**
* Tests if two string regions are equal.
* @param target target string.
* @param toffset character position in target to start comparison.
* @param other other string.
* @param ooffset character position in other to start comparison.
* @param len length of region.
* @return true if regions are equal.
*/
bool CachedDateFormat::regionMatches(
    const LogString& target,
    size_t toffset,
    const LogString& other,
    size_t ooffset,
    size_t len) {
    return target.compare(toffset, len, other, ooffset, len) == 0;
}

<commit_msg>LOGCXX-49: findMilllis signature used apr_time_t, needed log4cxx_time_t<commit_after>/*
 * Copyright 1999,2005 The Apache Software Foundation.
 *
 * 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.
 */
#define __STDC_CONSTANT_MACROS
#include <log4cxx/helpers/cacheddateformat.h>

#include <apr_time.h>
#include <log4cxx/helpers/pool.h>
#include <limits>
#include <log4cxx/helpers/exception.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::pattern;

/**
*  Supported digit set.  If the wrapped DateFormat uses
*  a different unit set, the millisecond pattern
*  will not be recognized and duplicate requests
*  will use the cache.
*/
const logchar* const CachedDateFormat::digits = LOG4CXX_STR("0123456789");

/**
 *  Expected representation of first magic number.
 */
const logchar* const CachedDateFormat::magicString1 = LOG4CXX_STR("654");

/**
 *  Expected representation of second magic number.
 */
const logchar* const CachedDateFormat::magicString2 = LOG4CXX_STR("987");

/**
 *  Expected representation of 0 milliseconds.
 */
const logchar* const CachedDateFormat::zeroString = LOG4CXX_STR("000");

#undef min

/**
 *  Creates a new CachedDateFormat object.
 *  @param dateFormat Date format, may not be null.
 *  @param expiration maximum cached range in milliseconds.
 *    If the dateFormat is known to be incompatible with the
 *      caching algorithm, use a value of 0 to totally disable
 *      caching or 1 to only use cache for duplicate requests.
 */
CachedDateFormat::CachedDateFormat(const DateFormatPtr& dateFormat,
        int expiration) :
       formatter(dateFormat),
       millisecondStart(0),
       slotBegin(std::numeric_limits<log4cxx_time_t>::min()),
       cache(50, LOG4CXX_STR(' ')),
       expiration(expiration),
       previousTime(std::numeric_limits<log4cxx_time_t>::min()) {
  if (dateFormat == NULL) {
    throw IllegalArgumentException("dateFormat cannot be null");
  }
  if (expiration < 0) {
    throw IllegalArgumentException("expiration must be non-negative");
  }
}

/**
 * Finds start of millisecond field in formatted time.
 * @param time long time, must be integral number of seconds
 * @param formatted String corresponding formatted string
 * @param formatter DateFormat date format
 * @return int position in string of first digit of milliseconds,
 *    -1 indicates no millisecond field, -2 indicates unrecognized
 *    field (likely RelativeTimeDateFormat)
 */
int CachedDateFormat::findMillisecondStart(
  log4cxx_time_t time, const LogString& formatted,
  const DateFormatPtr& formatter,
  Pool& pool) {

  apr_time_t slotBegin = (time / 1000000) * 1000000;
  if (slotBegin > time) {
     slotBegin -= 1000000;
  }
  int millis = (int) (time - slotBegin)/1000;

  int magic = magic1;
  LogString magicString(magicString1);
  if (millis == magic1) {
      magic = magic2;
      magicString = magicString2;
  }

  LogString plusMagic;
  formatter->format(plusMagic, slotBegin + magic, pool);

  /**
   *   If the string lengths differ then
   *      we can't use the cache except for duplicate requests.
   */
  if (plusMagic.length() != formatted.length()) {
      return UNRECOGNIZED_MILLISECONDS;
  } else {
      // find first difference between values
     for (LogString::size_type i = 0; i < formatted.length(); i++) {
        if (formatted[i] != plusMagic[i]) {
           //
           //   determine the expected digits for the base time
           LogString formattedMillis(LOG4CXX_STR("ABC"));
           millisecondFormat(millis, formattedMillis, 0);

           LogString plusZero;
           formatter->format(plusZero, slotBegin, pool);

           //   If the next 3 characters match the magic
           //      strings and the remaining fragments are identical
           //
           //
           if (plusZero.length() == formatted.length()
              && regionMatches(magicString, 0, plusMagic, i, magicString.length())
              && regionMatches(formattedMillis, 0, formatted, i, magicString.length())
              && regionMatches(zeroString, 0, plusZero, i, 3)
              && (formatted.length() == i + 3
                 || plusZero.compare(i + 3,
                       LogString::npos, plusMagic, i+3, LogString::npos) == 0)) {
              return i;
           } else {
              return UNRECOGNIZED_MILLISECONDS;
          }
        }
     }
  }
  return  NO_MILLISECONDS;
}

/**
 * Formats a millisecond count into a date/time string.
 *
 *  @param now Number of milliseconds after midnight 1 Jan 1970 GMT.
 *  @param sbuf the string buffer to write to
 */
 void CachedDateFormat::format(LogString& buf, log4cxx_time_t now, Pool& p) const {

  //
  // If the current requested time is identical to the previously
  //     requested time, then append the cache contents.
  //
  if (now == previousTime) {
       buf.append(cache);
       return;
  }

  //
  //   If millisecond pattern was not unrecognized
  //     (that is if it was found or milliseconds did not appear)
  //
  if (millisecondStart != UNRECOGNIZED_MILLISECONDS) {

      //    Check if the cache is still valid.
      //    If the requested time is within the same integral second
      //       as the last request and a shorter expiration was not requested.
      if (now < slotBegin + expiration
          && now >= slotBegin
          && now < slotBegin + 1000000L) {

          //
          //    if there was a millisecond field then update it
          //
          if (millisecondStart >= 0 ) {
              millisecondFormat((int) ((now - slotBegin)/1000), cache, millisecondStart);
          }
          //
          //   update the previously requested time
          //      (the slot begin should be unchanged)
          previousTime = now;
          buf.append(cache);
          return;
      }
  }

  //
  //  could not use previous value.
  //    Call underlying formatter to format date.
  cache.erase(cache.begin(), cache.end());
  formatter->format(cache, now, p);
  buf.append(cache);
  previousTime = now;
  slotBegin = (previousTime / 1000000) * 1000000;
  if (slotBegin > previousTime) {
      slotBegin -= 1000000;
  }

  //
  //    if the milliseconds field was previous found
  //       then reevaluate in case it moved.
  //
  if (millisecondStart >= 0) {
      millisecondStart = findMillisecondStart(now, cache, formatter, p);
  }
}

/**
 *   Formats a count of milliseconds (0-999) into a numeric representation.
 *   @param millis Millisecond coun between 0 and 999.
 *   @buf String buffer, may not be null.
 *   @offset Starting position in buffer, the length of the
 *       buffer must be at least offset + 3.
 */
void CachedDateFormat::millisecondFormat(int millis,
     LogString& buf,
     int offset) {
     buf[offset] = digits[ millis / 100];
     buf[offset + 1] = digits[(millis / 10) % 10];
     buf[offset + 2] = digits[millis  % 10];
 }

/**
 * Set timezone.
 *
 * @remarks Setting the timezone using getCalendar().setTimeZone()
 * will likely cause caching to misbehave.
 * @param timeZone TimeZone new timezone
 */
void CachedDateFormat::setTimeZone(const TimeZonePtr& timeZone) {
  formatter->setTimeZone(timeZone);
  previousTime = std::numeric_limits<log4cxx_time_t>::min();
  slotBegin = std::numeric_limits<log4cxx_time_t>::min();
}

void CachedDateFormat::numberFormat(LogString& s, int n, Pool& p) const {
  formatter->numberFormat(s, n, p);
}

/**
 * Gets maximum cache validity for the specified SimpleDateTime
 *    conversion pattern.
 *  @param pattern conversion pattern, may not be null.
 *  @returns Duration in microseconds from an integral second
 *      that the cache will return consistent results.
 */
int CachedDateFormat::getMaximumCacheValidity(const LogString& pattern) {
   //
   //   If there are more "S" in the pattern than just one "SSS" then
   //      (for example, "HH:mm:ss,SSS SSS"), then set the expiration to
   //      one millisecond which should only perform duplicate request caching.
   //
   size_t firstS = pattern.find(LOG4CXX_STR('S'));
   size_t len = pattern.length();
   //
   //   if there are no S's or
   //      three that start with the first S and no fourth S in the string
   //
   if (firstS == LogString::npos ||
       (len >= firstS + 3 && pattern.compare(firstS, 3, LOG4CXX_STR("SSS")) == 0
           && (len == firstS + 3 ||
                pattern.find(LOG4CXX_STR('S'), firstS + 3) == LogString::npos))) {
           return 1000000;
   }
   return 1000;
}

/**
* Tests if two string regions are equal.
* @param target target string.
* @param toffset character position in target to start comparison.
* @param other other string.
* @param ooffset character position in other to start comparison.
* @param len length of region.
* @return true if regions are equal.
*/
bool CachedDateFormat::regionMatches(
    const LogString& target,
    size_t toffset,
    const LogString& other,
    size_t ooffset,
    size_t len) {
    return target.compare(toffset, len, other, ooffset, len) == 0;
}

<|endoftext|>


<commit_before>#include <memory>

#include <boost/lexical_cast.hpp>

#include "celero/Celero.h"

#include <blackhole/log.hpp>
#include <blackhole/logger.hpp>
#include <blackhole/sink/null.hpp>
#include <blackhole/repository.hpp>

#define FIRE_DATETIME_GENERATOR
#define FIRE_STRING_FORMATTER

using namespace blackhole;

#ifdef FIRE_STRING_FORMATTER
enum level {
    debug,
    info,
    warning,
    error,
    critical
};

void map_timestamp(blackhole::aux::attachable_ostringstream& stream, const timeval& tv) {
    char str[64];

    struct tm tm;
    localtime_r((time_t *)&tv.tv_sec, &tm);
    if (std::strftime(str, sizeof(str), "%F %T", &tm)) {
        stream << str;
    } else {
        stream << "UNKNOWN";
    }
}

void map_severity(blackhole::aux::attachable_ostringstream& stream, const level& level) {
    static const char* descriptions[] = {
        "DEBUG",
        "INFO",
        "WARNING",
        "ERROR",
        "CRITICAL"
    };

    if (static_cast<std::size_t>(level) < sizeof(descriptions) / sizeof(*descriptions))
        stream << descriptions[level];
    else
        stream << level;
}

formatter::string_t fmt("[%(timestamp)s] [%(severity)s]: %(message)s");

void initialize() {
    mapping::value_t mapper;
    mapper.add<timeval>("timestamp", &map_timestamp);
    mapper.add<level>("severity", &map_severity);
    fmt.set_mapper(mapper);
}
#endif

int main(int argc, char** argv) {
#ifdef FIRE_STRING_FORMATTER
    initialize();
#endif
    celero::Run(argc, argv);
    return 0;
}

#ifdef FIRE_STRING_FORMATTER
static const int STRING_FORMATTER_SAMPLES = 30;
static const int STRING_FORMATTER_CALLS = 100000;
BASELINE(PureStringFormatter, Baseline, STRING_FORMATTER_SAMPLES, STRING_FORMATTER_CALLS) {
    log::record_t record;
    record.attributes.insert(keyword::message() = "Something bad is going on but I can handle it");

    timeval tv;
    gettimeofday(&tv, nullptr);
    record.attributes.insert(keyword::timestamp() = tv);
    record.attributes.insert(keyword::severity<level>() = level::warning);
    celero::DoNotOptimizeAway(fmt.format(record));
}
#endif

#ifdef FIRE_DATETIME_GENERATOR
#include <blackhole/detail/datetime.hpp>

static const int DATETIME_GENERATOR_SAMPLES = 30;
static const int DATETIME_GENERATOR_CALLS = 100000;
BASELINE(DatetimeGenerator, Baseline, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    char buf[64];
    strftime(buf, 64, "%Y-%m-%d %H:%M:%S", &tm);
    celero::DoNotOptimizeAway(buf);
}

BENCHMARK(DatetimeGenerator, Generator, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    static std::string str;
    static aux::datetime::generator_t generator(aux::datetime::generator_factory_t::make("%Y-%m-%d %H:%M:%S"));
    static aux::attachable_ostringstream stream(str);

    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    generator(stream, tm);
    celero::DoNotOptimizeAway(str);
    str.clear();
}

BASELINE(DatetimeGeneratorUsingLocale, Baseline, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    char buf[64];
    strftime(buf, 64, "%c", &tm);
    celero::DoNotOptimizeAway(buf);
}

BENCHMARK(DatetimeGeneratorUsingLocale, Generator, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    static std::string str;
    static aux::datetime::generator_t generator(aux::datetime::generator_factory_t::make("%c"));
    static aux::attachable_ostringstream stream(str);

    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    generator(stream, tm);
    celero::DoNotOptimizeAway(str);
    str.clear();
}
#endif
<commit_msg>[Benchmarking] Added benchmark to measure full logging cycle.<commit_after>#include <memory>

#include <boost/lexical_cast.hpp>

#include "celero/Celero.h"

#include <blackhole/log.hpp>
#include <blackhole/logger.hpp>
#include <blackhole/sink/null.hpp>
#include <blackhole/repository.hpp>

#define FIRE_DATETIME_GENERATOR
#define FIRE_STRING_FORMATTER
#define FIRE_STRING_TO_NULL_LOGGING

const char MESSAGE_LONG[] = "Something bad is going on but I can handle it";

using namespace blackhole;

#ifdef FIRE_STRING_FORMATTER
enum level {
    debug,
    info,
    warning,
    error,
    critical
};

void map_timestamp(blackhole::aux::attachable_ostringstream& stream, const timeval& tv) {
    char str[64];

    struct tm tm;
    localtime_r((time_t *)&tv.tv_sec, &tm);
    if (std::strftime(str, sizeof(str), "%F %T", &tm)) {
        stream << str;
    } else {
        stream << "UNKNOWN";
    }
}

void map_severity(blackhole::aux::attachable_ostringstream& stream, const level& level) {
    static const char* descriptions[] = {
        "DEBUG",
        "INFO",
        "WARNING",
        "ERROR",
        "CRITICAL"
    };

    if (static_cast<std::size_t>(level) < sizeof(descriptions) / sizeof(*descriptions))
        stream << descriptions[level];
    else
        stream << level;
}

formatter::string_t fmt("[%(timestamp)s] [%(severity)s]: %(message)s");

void initialize() {
    mapping::value_t mapper;
    mapper.add<timeval>("timestamp", &map_timestamp);
    mapper.add<level>("severity", &map_severity);
    fmt.set_mapper(mapper);
}
#endif

int main(int argc, char** argv) {
#ifdef FIRE_STRING_FORMATTER
    initialize();
#endif
    celero::Run(argc, argv);
    return 0;
}

#ifdef FIRE_STRING_FORMATTER
static const int STRING_FORMATTER_SAMPLES = 30;
static const int STRING_FORMATTER_CALLS = 100000;
BASELINE(PureStringFormatter, Baseline, STRING_FORMATTER_SAMPLES, STRING_FORMATTER_CALLS) {
    log::record_t record;
    record.attributes.insert(keyword::message() = "Something bad is going on but I can handle it");

    timeval tv;
    gettimeofday(&tv, nullptr);
    record.attributes.insert(keyword::timestamp() = tv);
    record.attributes.insert(keyword::severity<level>() = level::warning);
    celero::DoNotOptimizeAway(fmt.format(record));
}
#endif

#ifdef FIRE_DATETIME_GENERATOR
#include <blackhole/detail/datetime.hpp>

static const int DATETIME_GENERATOR_SAMPLES = 30;
static const int DATETIME_GENERATOR_CALLS = 100000;
BASELINE(DatetimeGenerator, Baseline, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    char buf[64];
    strftime(buf, 64, "%Y-%m-%d %H:%M:%S", &tm);
    celero::DoNotOptimizeAway(buf);
}

BENCHMARK(DatetimeGenerator, Generator, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    static std::string str;
    static aux::datetime::generator_t generator(aux::datetime::generator_factory_t::make("%Y-%m-%d %H:%M:%S"));
    static aux::attachable_ostringstream stream(str);

    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    generator(stream, tm);
    celero::DoNotOptimizeAway(str);
    str.clear();
}

BASELINE(DatetimeGeneratorUsingLocale, Baseline, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    char buf[64];
    strftime(buf, 64, "%c", &tm);
    celero::DoNotOptimizeAway(buf);
}

BENCHMARK(DatetimeGeneratorUsingLocale, Generator, DATETIME_GENERATOR_SAMPLES, DATETIME_GENERATOR_CALLS) {
    static std::string str;
    static aux::datetime::generator_t generator(aux::datetime::generator_factory_t::make("%c"));
    static aux::attachable_ostringstream stream(str);

    std::time_t time = std::time(nullptr);
    std::tm tm;
    localtime_r(&time, &tm);
    generator(stream, tm);
    celero::DoNotOptimizeAway(str);
    str.clear();
}
#endif

#ifdef FIRE_STRING_TO_NULL_LOGGING
#include <blackhole/sink/null.hpp>

static const int LOG_STRING_TO_NULL_SAMPLES = 30;
static const int LOG_STRING_TO_NULL_CALLS = 200000;

namespace log_string_to_null {

enum level {
    debug
};

verbose_logger_t<level> init_log() {
    auto formatter = utils::make_unique<
        formatter::string_t
    >("%(message)s");

    auto sink = utils::make_unique<
        sink::null_t
    >();

    auto frontend = utils::make_unique<
        frontend_t<
            formatter::string_t,
            sink::null_t
        >
    >(std::move(formatter), std::move(sink));

    verbose_logger_t<level> log;
    log.add_frontend(std::move(frontend));
    return log;
}

} // namespace log_string_to_null

BASELINE(LogStringToNull, Baseline, LOG_STRING_TO_NULL_SAMPLES, LOG_STRING_TO_NULL_CALLS) {
    static verbose_logger_t<log_string_to_null::level> log =
        log_string_to_null::init_log();

    BH_LOG(log, log_string_to_null::debug, MESSAGE_LONG)(attribute::list({
        {"int", 42},
        {"string", "le string"},
    }));
}
#endif
<|endoftext|>


<commit_before>#ifndef _LINALG_HPP_
#define _LINALG_HPP_

#include "blas_wrap.hpp"

#ifdef _PARALLEL_
# include <omp.h>
#endif

#if defined(_PARALLEL_) || defined(__INTEL_MKL__)
# include "mkl.h"
#endif

#include <assert.h>
#include <cstddef>
#include <time.h>

#include <cmath>
#include <iostream>

#include "timing.hpp"

// This is a basic templated matrix class.
// It stores the matrix data, the stride, and the dimensions.
// The variable is_view indicates whether or not the data is owned
// by this instance.
template <typename Scalar>
class Matrix {
public:

  Matrix(Scalar *data, int stride, int m, int n, Scalar multiplier, bool is_view) :
    data_(data), stride_(stride), m_(m), n_(n), multiplier_(multiplier), is_view_(is_view) {
    if (!is_view) {
      allocate();
    }
  }

  Matrix(Scalar *data, int stride, int m, int n, Scalar multiplier) :
    Matrix(data, stride, m, n, multiplier, true) {}
  Matrix(Scalar *data, int stride, int m, int n) : Matrix(data, stride, m, n, Scalar(1)) {}

  Matrix(int m, int n, Scalar multiplier) : Matrix(NULL, m, m, n, multiplier, false) {}
  Matrix(int m, int n) : Matrix(m, n, Scalar(1)) {}
  Matrix(int n=0) : Matrix(n, n) {}

  // Copy constructor
  Matrix(Matrix<Scalar>& that) : Matrix(NULL, that.m(), that.m(), that.n(),
                                        that.multiplier(), false) {
    Scalar *that_data = that.data();
    int that_stride = that.stride();
    for (int j = 0; j < n_; ++j) {
      for (int i = 0; i < m_; ++i) {
        data_[i + j * stride_] = that_data[i + j * that_stride];
      }
    }
  }

  // Move constructor
  Matrix(Matrix<Scalar>&& that) : Matrix() {
    swap(*this, that);
  }

  // copy assignment
  Matrix<Scalar>& operator=(Matrix<Scalar> that) {
    swap(*this, that);
    return *this;
  }

  friend void swap(Matrix<Scalar>& first, Matrix<Scalar>& second) {
    using std::swap;
    swap(first.m_, second.m_);
    swap(first.n_, second.n_);
    swap(first.stride_, second.stride_);
    swap(first.is_view_, second.is_view_);
    swap(first.data_, second.data_);
    swap(first.multiplier_, second.multiplier_);
  }

  // Get a view of a subblock of the matrix.
  // num_block_rows and num_block_cols are the number of block rows and columns
  // row_ind and col_ind are the indices (1-indexed) of the block
  Matrix<Scalar> Subblock(int num_block_rows, int num_block_cols, int row_ind,
                          int col_ind) {
    std::pair<int, int> row_data = IndexData(m_, num_block_rows, row_ind);
    std::pair<int, int> col_data = IndexData(n_, num_block_cols, col_ind);
    return Submatrix(row_data.first, col_data.first, row_data.second, col_data.second);
  }

  Matrix<Scalar> Submatrix(int start_row, int start_col, int num_rows,
                           int num_cols) {
    return Matrix<Scalar>(data(start_row, start_col), stride_, num_rows, num_cols, multiplier_);
  }

  ~Matrix() {
    if (data_ != NULL && !is_view_ && m_ > 0 && n_ > 0) {
      deallocate();
    }
  }

  Scalar *data() { return data_; }
  Scalar *data(int i, int j) { return data_ + i + j * stride_; }
  int stride() { return stride_; }
  int m() { return m_; }
  int n() { return n_; }

  int height() { return m_; }
  int width() { return n_; }

  const Scalar& operator()(int i, int j) const {  return data_[i + j * stride_]; }
  Scalar& operator()(int i, int j) {  return data_[i + j * stride_]; }

  void allocate() {
    if (n_ > 0 && m_ > 0) {
      assert(stride_ >= m_);
#ifdef __INTEL_MKL__
      int alignment = 32;
      data_ = static_cast<Scalar *>(mkl_malloc(sizeof(Scalar) * m_ * n_, alignment));
#else
      data_ = new Scalar[m_ * n_];
#endif
      assert(data_ != NULL);
    }
  }

  void deallocate() {
    if (data_ != NULL) {
#ifdef __INTEL_MKL__
      mkl_free(data_);
#else
      delete[] data_;
#endif
      data_ = NULL;
    }
  }

  void UpdateMultiplier(Scalar multiplier) { multiplier_ *= multiplier; }
  void set_multiplier(Scalar multiplier) { multiplier_ = multiplier; }
  Scalar multiplier() { return multiplier_; }

private:
  // Return pair of (starting index, number of indices)
  std::pair<int, int> IndexData(int total, int num_block, int ind) {
    int step = total / num_block;
    // Determine starting index
    int start = step * (ind - 1);
    return std::pair<int, int>(start, step);
  }

  Scalar *data_;
  int stride_;
  int m_;
  int n_;
  bool is_view_;
  Scalar multiplier_;
};

// Perform one step of dynamic peeling in the multiplication
//            C = A * B + beta C
// This should be called once at the end of a recursive fast
// matrix multiplication function.
// dim1, dim2, and dim3 refer to the (M, K, N) dimensions of
// the fast algorithm (M x K times K x N base case).
template<typename Scalar>
void DynamicPeeling(Matrix<Scalar>& A, Matrix<Scalar>& B, Matrix<Scalar>& C,
                    int dim1, int dim2, int dim3, Scalar beta) {
  assert(A.m() == C.m() && A.n() == B.m() && B.n() == C.n());
  assert(A.m() > 0 && A.n() > 0);
  int extra_rows_A = A.m() - (A.m() / dim1) * dim1;
  int extra_cols_A = A.n() - (A.n() / dim2) * dim2;
  int extra_rows_B = B.m() - (B.m() / dim2) * dim2;
  int extra_cols_B = B.n() - (B.n() / dim3) * dim3;
  assert(extra_cols_A == extra_rows_B);

  // Adjust part handled by fast matrix multiplication.
  // Add far column of A outer product bottom row B
  if (extra_cols_A > 0) {
    // In Strassen, this looks like C([1, 2], [1, 2]) += A([1, 2], 3) * B(3, [1, 2])
    int row_dim = A.m() - extra_rows_A;
    int col_dim = B.n() - extra_cols_B;
    int inner_dim_start = A.n() - extra_cols_A;
    Matrix<Scalar> A_extra = A.Submatrix(0, inner_dim_start, row_dim, extra_cols_A);
    Matrix<Scalar> B_extra = B.Submatrix(inner_dim_start, 0, extra_rows_B, col_dim);
    Matrix<Scalar> C_extra = C.Submatrix(0, 0, row_dim, col_dim);
    MatMul(A_extra, B_extra, C_extra, Scalar(1.0));
  }

  // Adjust for far right columns of C
  if (extra_cols_B > 0) {
    // In Strassen, this looks like C(:, 3) = A * B(:, 3)
    int start_ind = B.n() - extra_cols_B;
    Matrix<Scalar> B_extra = B.Submatrix(0, start_ind, B.m(), extra_cols_B);
    Matrix<Scalar> C_extra = C.Submatrix(0, start_ind, C.m(), extra_cols_B);
    MatMul(A, B_extra, C_extra, beta);
  }

  // Adjust for bottom rows of C
  if (extra_rows_A > 0) {
    // In Strassen, this looks like C(3, [1, 2]) = A(3, :) * B(:, [1, 2])
    int start_ind = A.m() - extra_rows_A;
    int num_cols = B.n() - extra_cols_B;
    Matrix<Scalar> A_extra = A.Submatrix(start_ind, 0, extra_rows_A, A.n());
    Matrix<Scalar> B_extra = B.Submatrix(0, 0, B.m(), num_cols);
    Matrix<Scalar> C_extra = C.Submatrix(start_ind, 0, extra_rows_A, num_cols);
    MatMul(A_extra, B_extra, C_extra, beta);
  }
}

// Streams out all entries in the matrix.
template <typename Scalar>
std::ostream& operator<<(std::ostream& os, Matrix<Scalar>& mat) {
  for (int i = 0; i < mat.m(); ++i) {
    for (int j = 0; j < mat.n(); ++j) {
      os << C(i, j) << " ";
    }
    os << std::endl;
  }
  return os;
}

// C <-- A * B + beta * C
template <typename Scalar>
void MatMul(Matrix<Scalar>& A, Matrix<Scalar>& B, Matrix<Scalar>& C,
            Scalar beta=Scalar(0.0)) {
  assert(A.m() == C.m() && A.n() == B.m() && B.n() == C.n());
  assert(A.m() > 0 && A.n() > 0);
  Scalar alpha = C.multiplier();
  blas::Gemm('N', 'N', A.m(), B.n(), A.n(), A.data(), A.stride(), B.data(),
             B.stride(), C.data(), C.stride(), alpha, beta);
}

// C <-- alpha * A + C.  n is the number of entries.
template<typename Scalar>
void AxpyWrap(Scalar *C, Scalar *A, int n, Scalar alpha) {
  blas::Axpy(C, A, n, alpha, 1, 1);
}

// max_ij |a_ij - b_ij| / |a_ij|
template<typename Scalar>
double MaxRelativeDiff(Matrix<Scalar>& A, Matrix<Scalar>& B) {
  assert(A.m() == B.m() && A.n() == B.n());
  double max_rel_diff = 0;
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = A(i, j);
      Scalar b = B(i, j);
      Scalar curr_rel_diff = std::abs(a - b) / std::abs(a);
      if (curr_rel_diff > max_rel_diff) {
        max_rel_diff = curr_rel_diff;
      }
    }
  }
  return max_rel_diff;
}

// Frobenius norm difference: \| A - B \|_F
template<typename Scalar>
double FrobeniusDiff(Matrix<Scalar>& A, Matrix<Scalar>& B) {
  assert(A.m() == B.m() && A.n() == B.n());
  double diff = 0.0;
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = A(i, j);
      Scalar b = B(i, j);
      Scalar local_diff = a - b;
      diff += local_diff * local_diff;
    }
  }
  return sqrt(diff);
}

// Frobenius norm \| A \|_F
template<typename Scalar>
double FrobeniusNorm(Matrix<Scalar>& A) {
  double norm = 0.0;
  const int strideA = A.stride();
  const Scalar *dataA = A.data();
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = dataA[i + j * strideA];
      norm += a * a;
    }
  }
  return sqrt(norm);
}

// C <-- -A
template<typename Scalar>
void Negate(Matrix<Scalar>& A, Matrix<Scalar>& C) {
  assert(A.m() == C.m() && A.n() == C.n());
#ifdef _PARALLEL_
# pragma omp parallel for collapse(2)
#endif
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = -A(i, j);
    }
  }
}

// C <-- A
template<typename Scalar>
void Copy(Matrix<Scalar>& A, Matrix<Scalar>& C) {
  assert(A.m() == C.m() && A.n() == C.n());
#ifdef _PARALLEL_
# pragma omp parallel for collapse(2)
#endif
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = A(i, j);
    }
  }
}

// C = alpha1 * A1
template <typename Scalar>
void Copy(Matrix<Scalar>& A1,
          Scalar alpha1,
          Matrix<Scalar>& C) {
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = alpha1 * A1(i, j);
    }
  }
}

// C += alpha1 * A1
template <typename Scalar>
void UpdateAddDaxpy(Matrix<Scalar>& A1,
                    Scalar alpha1,
                    Matrix<Scalar>& C) {
  const int strideA1 = A1.stride();
  Scalar *dataA1 = A1.data();

  const int strideC = C.stride();
  Scalar *dataC = C.data();

  for (int j = 0; j < C.n(); ++j) {
    Scalar *dataA_curr = dataA1 + j * strideA1;
    Scalar *dataC_curr = dataC + j * strideC;
    AxpyWrap(dataC_curr, dataA_curr, C.m(), alpha1);
  }
}

// C := 0
template <typename Scalar>
void ZeroOut(Matrix<Scalar>& C) {
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = Scalar(0);
    }
  }
}

// Generate a matrix with random uniform entries on [0, 1]
template <typename Scalar>
Matrix<Scalar> RandomMatrix(int m, int n) {
  Matrix<Scalar> A(m, n);
  // We can use fancier C++11 random number generators, but they are
  // still slow on some systems.
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      A(i, j) =  static_cast<double>(rand()) / RAND_MAX;
    }
  }
  return A;
}

#endif  // _LINALG_HPP_
<commit_msg>clean up code<commit_after>#ifndef _LINALG_HPP_
#define _LINALG_HPP_

#include "blas_wrap.hpp"

#ifdef _PARALLEL_
# include <omp.h>
#endif

#if defined(_PARALLEL_) || defined(__INTEL_MKL__)
# include "mkl.h"
#endif

#include <assert.h>
#include <cstddef>
#include <time.h>

#include <cmath>
#include <iostream>

#include "timing.hpp"

// This is a basic templated matrix class.
// It stores the matrix data, the stride, and the dimensions.
// The variable is_view indicates whether or not the data is owned
// by this instance.
template <typename Scalar>
class Matrix {
public:

  Matrix(Scalar *data, int stride, int m, int n, Scalar multiplier, bool is_view) :
    data_(data), stride_(stride), m_(m), n_(n), multiplier_(multiplier), is_view_(is_view) {
    if (!is_view) {
      allocate();
    }
  }

  Matrix(Scalar *data, int stride, int m, int n, Scalar multiplier) :
    Matrix(data, stride, m, n, multiplier, true) {}
  Matrix(Scalar *data, int stride, int m, int n) : Matrix(data, stride, m, n, Scalar(1)) {}

  Matrix(int m, int n, Scalar multiplier) : Matrix(NULL, m, m, n, multiplier, false) {}
  Matrix(int m, int n) : Matrix(m, n, Scalar(1)) {}
  Matrix(int n=0) : Matrix(n, n) {}

  // Copy constructor
  Matrix(Matrix<Scalar>& that) : Matrix(NULL, that.m(), that.m(), that.n(),
                                        that.multiplier(), false) {
    Scalar *that_data = that.data();
    int that_stride = that.stride();
    for (int j = 0; j < n_; ++j) {
      for (int i = 0; i < m_; ++i) {
        data_[i + j * stride_] = that_data[i + j * that_stride];
      }
    }
  }

  // Move constructor
  Matrix(Matrix<Scalar>&& that) : Matrix() {
    swap(*this, that);
  }

  // copy assignment
  Matrix<Scalar>& operator=(Matrix<Scalar> that) {
    swap(*this, that);
    return *this;
  }

  friend void swap(Matrix<Scalar>& first, Matrix<Scalar>& second) {
    using std::swap;
    swap(first.m_, second.m_);
    swap(first.n_, second.n_);
    swap(first.stride_, second.stride_);
    swap(first.is_view_, second.is_view_);
    swap(first.data_, second.data_);
    swap(first.multiplier_, second.multiplier_);
  }

  // Get a view of a subblock of the matrix.
  // num_block_rows and num_block_cols are the number of block rows and columns
  // row_ind and col_ind are the indices (1-indexed) of the block
  Matrix<Scalar> Subblock(int num_block_rows, int num_block_cols, int row_ind,
                          int col_ind) {
    std::pair<int, int> row_data = IndexData(m_, num_block_rows, row_ind);
    std::pair<int, int> col_data = IndexData(n_, num_block_cols, col_ind);
    return Submatrix(row_data.first, col_data.first, row_data.second, col_data.second);
  }

  Matrix<Scalar> Submatrix(int start_row, int start_col, int num_rows,
                           int num_cols) {
    return Matrix<Scalar>(data(start_row, start_col), stride_, num_rows, num_cols, multiplier_);
  }

  ~Matrix() {
    if (data_ != NULL && !is_view_ && m_ > 0 && n_ > 0) {
      deallocate();
    }
  }

  Scalar *data() { return data_; }
  Scalar *data(int i, int j) { return data_ + i + j * stride_; }
  int stride() { return stride_; }
  int m() { return m_; }
  int n() { return n_; }

  int height() { return m_; }
  int width() { return n_; }

  const Scalar& operator()(int i, int j) const {  return data_[i + j * stride_]; }
  Scalar& operator()(int i, int j) {  return data_[i + j * stride_]; }

  void allocate() {
    if (n_ > 0 && m_ > 0) {
      assert(stride_ >= m_);
#ifdef __INTEL_MKL__
      int alignment = 32;
      data_ = static_cast<Scalar *>(mkl_malloc(sizeof(Scalar) * m_ * n_, alignment));
#else
      data_ = new Scalar[m_ * n_];
#endif
      assert(data_ != NULL);
    }
  }

  void deallocate() {
    if (data_ != NULL) {
#ifdef __INTEL_MKL__
      mkl_free(data_);
#else
      delete[] data_;
#endif
      data_ = NULL;
    }
  }

  void UpdateMultiplier(Scalar multiplier) { multiplier_ *= multiplier; }
  void set_multiplier(Scalar multiplier) { multiplier_ = multiplier; }
  Scalar multiplier() { return multiplier_; }

private:
  // Return pair of (starting index, number of indices)
  std::pair<int, int> IndexData(int total, int num_block, int ind) {
    int step = total / num_block;
    // Determine starting index
    int start = step * (ind - 1);
    return std::pair<int, int>(start, step);
  }

  Scalar *data_;
  int stride_;
  int m_;
  int n_;
  bool is_view_;
  Scalar multiplier_;
};

// Perform one step of dynamic peeling in the multiplication
//            C = A * B + beta C
// This should be called once at the end of a recursive fast
// matrix multiplication function.
// dim1, dim2, and dim3 refer to the (M, K, N) dimensions of
// the fast algorithm (M x K times K x N base case).
template<typename Scalar>
void DynamicPeeling(Matrix<Scalar>& A, Matrix<Scalar>& B, Matrix<Scalar>& C,
                    int dim1, int dim2, int dim3, Scalar beta) {
  assert(A.m() == C.m() && A.n() == B.m() && B.n() == C.n());
  assert(A.m() > 0 && A.n() > 0);
  int extra_rows_A = A.m() - (A.m() / dim1) * dim1;
  int extra_cols_A = A.n() - (A.n() / dim2) * dim2;
  int extra_rows_B = B.m() - (B.m() / dim2) * dim2;
  int extra_cols_B = B.n() - (B.n() / dim3) * dim3;
  assert(extra_cols_A == extra_rows_B);

  // Adjust part handled by fast matrix multiplication.
  // Add far column of A outer product bottom row B
  if (extra_cols_A > 0) {
    // In Strassen, this looks like C([1, 2], [1, 2]) += A([1, 2], 3) * B(3, [1, 2])
    int row_dim = A.m() - extra_rows_A;
    int col_dim = B.n() - extra_cols_B;
    int inner_dim_start = A.n() - extra_cols_A;
    Matrix<Scalar> A_extra = A.Submatrix(0, inner_dim_start, row_dim, extra_cols_A);
    Matrix<Scalar> B_extra = B.Submatrix(inner_dim_start, 0, extra_rows_B, col_dim);
    Matrix<Scalar> C_extra = C.Submatrix(0, 0, row_dim, col_dim);
    MatMul(A_extra, B_extra, C_extra, Scalar(1.0));
  }

  // Adjust for far right columns of C
  if (extra_cols_B > 0) {
    // In Strassen, this looks like C(:, 3) = A * B(:, 3)
    int start_ind = B.n() - extra_cols_B;
    Matrix<Scalar> B_extra = B.Submatrix(0, start_ind, B.m(), extra_cols_B);
    Matrix<Scalar> C_extra = C.Submatrix(0, start_ind, C.m(), extra_cols_B);
    MatMul(A, B_extra, C_extra, beta);
  }

  // Adjust for bottom rows of C
  if (extra_rows_A > 0) {
    // In Strassen, this looks like C(3, [1, 2]) = A(3, :) * B(:, [1, 2])
    int start_ind = A.m() - extra_rows_A;
    int num_cols = B.n() - extra_cols_B;
    Matrix<Scalar> A_extra = A.Submatrix(start_ind, 0, extra_rows_A, A.n());
    Matrix<Scalar> B_extra = B.Submatrix(0, 0, B.m(), num_cols);
    Matrix<Scalar> C_extra = C.Submatrix(start_ind, 0, extra_rows_A, num_cols);
    MatMul(A_extra, B_extra, C_extra, beta);
  }
}

// Streams out all entries in the matrix.
template <typename Scalar>
std::ostream& operator<<(std::ostream& os, Matrix<Scalar>& mat) {
  for (int i = 0; i < mat.m(); ++i) {
    for (int j = 0; j < mat.n(); ++j) {
      os << C(i, j) << " ";
    }
    os << std::endl;
  }
  return os;
}

// C <-- A * B + beta * C
template <typename Scalar>
void MatMul(Matrix<Scalar>& A, Matrix<Scalar>& B, Matrix<Scalar>& C,
            Scalar beta=Scalar(0.0)) {
  assert(A.m() == C.m() && A.n() == B.m() && B.n() == C.n());
  assert(A.m() > 0 && A.n() > 0);
  Scalar alpha = C.multiplier();
  blas::Gemm('N', 'N', A.m(), B.n(), A.n(), A.data(), A.stride(), B.data(),
             B.stride(), C.data(), C.stride(), alpha, beta);
}

// C <-- alpha * A + C.  n is the number of entries.
template<typename Scalar>
void AxpyWrap(Scalar *C, Scalar *A, int n, Scalar alpha) {
  blas::Axpy(C, A, n, alpha, 1, 1);
}

// max_ij |a_ij - b_ij| / |a_ij|
template<typename Scalar>
double MaxRelativeDiff(Matrix<Scalar>& A, Matrix<Scalar>& B) {
  assert(A.m() == B.m() && A.n() == B.n());
  double max_rel_diff = 0;
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = A(i, j);
      Scalar b = B(i, j);
      Scalar curr_rel_diff = std::abs(a - b) / std::abs(a);
      if (curr_rel_diff > max_rel_diff) {
        max_rel_diff = curr_rel_diff;
      }
    }
  }
  return max_rel_diff;
}

// Frobenius norm difference: \| A - B \|_F
template<typename Scalar>
double FrobeniusDiff(Matrix<Scalar>& A, Matrix<Scalar>& B) {
  assert(A.m() == B.m() && A.n() == B.n());
  double diff = 0.0;
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = A(i, j);
      Scalar b = B(i, j);
      Scalar local_diff = a - b;
      diff += local_diff * local_diff;
    }
  }
  return sqrt(diff);
}

// Frobenius norm \| A \|_F
template<typename Scalar>
double FrobeniusNorm(Matrix<Scalar>& A) {
  double norm = 0.0;
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      Scalar a = A(i, j);
      norm += a * a;
    }
  }
  return sqrt(norm);
}

// C <-- -A
template<typename Scalar>
void Negate(Matrix<Scalar>& A, Matrix<Scalar>& C) {
  assert(A.m() == C.m() && A.n() == C.n());
#ifdef _PARALLEL_
# pragma omp parallel for collapse(2)
#endif
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = -A(i, j);
    }
  }
}

// C <-- A
template<typename Scalar>
void Copy(Matrix<Scalar>& A, Matrix<Scalar>& C) {
  assert(A.m() == C.m() && A.n() == C.n());
#ifdef _PARALLEL_
# pragma omp parallel for collapse(2)
#endif
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = A(i, j);
    }
  }
}

// C = alpha1 * A1
template <typename Scalar>
void Copy(Matrix<Scalar>& A1,
          Scalar alpha1,
          Matrix<Scalar>& C) {
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = alpha1 * A1(i, j);
    }
  }
}

// C += alpha1 * A1
template <typename Scalar>
void UpdateAddDaxpy(Matrix<Scalar>& A1,
                    Scalar alpha1,
                    Matrix<Scalar>& C) {
  const int strideA1 = A1.stride();
  Scalar *dataA1 = A1.data();

  const int strideC = C.stride();
  Scalar *dataC = C.data();

  for (int j = 0; j < C.n(); ++j) {
    Scalar *dataA_curr = dataA1 + j * strideA1;
    Scalar *dataC_curr = dataC + j * strideC;
    AxpyWrap(dataC_curr, dataA_curr, C.m(), alpha1);
  }
}

// C := 0
template <typename Scalar>
void ZeroOut(Matrix<Scalar>& C) {
  for (int j = 0; j < C.n(); ++j) {
    for (int i = 0; i < C.m(); ++i) {
      C(i, j) = Scalar(0);
    }
  }
}

// Generate a matrix with random uniform entries on [0, 1]
template <typename Scalar>
Matrix<Scalar> RandomMatrix(int m, int n) {
  Matrix<Scalar> A(m, n);
  // We can use fancier C++11 random number generators, but they are
  // still slow on some systems.
  for (int j = 0; j < A.n(); ++j) {
    for (int i = 0; i < A.m(); ++i) {
      A(i, j) =  static_cast<double>(rand()) / RAND_MAX;
    }
  }
  return A;
}

#endif  // _LINALG_HPP_
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <stdexcept>
#include <vector>

#include <boost/program_options.hpp>

#include <pkmnsim/base_pkmn.hpp>

#include "type_stats_common.hpp"

using namespace pkmnsim;
using namespace std;
namespace po = boost::program_options;

int main(int argc, char *argv[])
{
    //Taking in user options
    int gen;
    string type1;
    string type2;

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "Display this help message.")
        ("gen", po::value<int>(&gen)->default_value(5), "Which generation to use")
        ("type1", po::value<string>(&type1)->default_value("None"), "Type 1 to search for")
        ("type2", po::value<string>(&type2)->default_value("None"), "Type 2 to search for, default=None")
        ("lax", "If only specifying one type, specify '--lax' to include any type combination with that type")
        ("evolved", "Only check fully evolved Pokémon")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

	bool lax = (vm.count("lax") > 0);
	bool evolved = (vm.count("evolved") > 0);

    //Process help or user mistake
    if(vm.count("help") > 0)
    {
        cout << "\nGet Type Stats - " << desc << endl;
        return EXIT_FAILURE;
    }
    if(type1 == "None")
    {
        cout << "\nSpecify a type with type1=(type)." << endl;
        cout << "\nSearch Type Combo - " << desc << endl;
        return EXIT_FAILURE;
    }

    //Preparing stat_st vectors
	vector<stat_st> highest_stats, lowest_stats;
    sort_pokemon_by_stats(type1, type2, highest_stats, lowest_stats, gen, lax, evolved);

    //Format output
    string type_str;
    if(type2 != "None") type_str = type1 + "/" + type2;
    else
    {
        if(lax) type_str = type1 + "/Any";
        else type_str = type1;
    }

    //Output highest/lowest stats
    cout << "\nHighest/lowest stats for type " << type_str << " (Generation " << gen << "):" << endl;

    for(int i = 0; i < highest_stats.size(); i++)
    {
        cout << endl << highest_stats[i].stat_name << endl;
        cout << " * Highest: " << highest_stats[i].pkmn_name << " (" << highest_stats[i].stat_value << ")\n";
        cout << " * Lowest: " << lowest_stats[i].pkmn_name << " (" << lowest_stats[i].stat_value << ")\n";
    }
    cout << endl;

    return EXIT_SUCCESS;
}
<commit_msg>get_type_stats: throw error if type1 == type 2<commit_after>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <stdexcept>
#include <vector>

#include <boost/program_options.hpp>

#include <pkmnsim/base_pkmn.hpp>

#include "type_stats_common.hpp"

using namespace pkmnsim;
using namespace std;
namespace po = boost::program_options;

int main(int argc, char *argv[])
{
    //Taking in user options
    int gen;
    string type1;
    string type2;

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "Display this help message.")
        ("gen", po::value<int>(&gen)->default_value(5), "Which generation to use")
        ("type1", po::value<string>(&type1)->default_value("None"), "Type 1 to search for")
        ("type2", po::value<string>(&type2)->default_value("None"), "Type 2 to search for, default=None")
        ("lax", "If only specifying one type, specify '--lax' to include any type combination with that type")
        ("evolved", "Only check fully evolved Pokémon")
    ;
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

	bool lax = (vm.count("lax") > 0);
	bool evolved = (vm.count("evolved") > 0);

    //Process help or user mistake
    if(vm.count("help") > 0)
    {
        cout << "\nGet Type Stats - " << desc << endl;
        return EXIT_FAILURE;
    }
    if(type1 == "None")
    {
        cout << "\nSpecify a type with type1=(type)." << endl;
        cout << "\nSearch Type Combo - " << desc << endl;
        return EXIT_FAILURE;
    }
    if(type1 == type2)
    {
        cerr << "\nType 1 cannot equal Type 2. Specify a single type or two different types." << endl;
        return EXIT_FAILURE;
    }

    //Preparing stat_st vectors
	vector<stat_st> highest_stats, lowest_stats;
    sort_pokemon_by_stats(type1, type2, highest_stats, lowest_stats, gen, lax, evolved);

    //Format output
    string type_str;
    if(type2 != "None") type_str = type1 + "/" + type2;
    else
    {
        if(lax) type_str = type1 + "/Any";
        else type_str = type1;
    }

    //Output highest/lowest stats
    cout << "\nHighest/lowest stats for type " << type_str << " (Generation " << gen << "):" << endl;

    for(int i = 0; i < highest_stats.size(); i++)
    {
        cout << endl << highest_stats[i].stat_name << endl;
        cout << " * Highest: " << highest_stats[i].pkmn_name << " (" << highest_stats[i].stat_value << ")\n";
        cout << " * Lowest: " << lowest_stats[i].pkmn_name << " (" << lowest_stats[i].stat_value << ")\n";
    }
    cout << endl;

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/////////////////////////////////////////
//
//             OpenLieroX
//
// code under LGPL, based on JasonBs work,
// enhanced by Dark Charlie and Albert Zeyer
//
//
/////////////////////////////////////////

// Main menu
// Created 30/6/02
// Jason Boettcher

#include <assert.h>

#include "LieroX.h"
#include "AuxLib.h"
#include "Graphics.h"
#include "Menu.h"
#include "GfxPrimitives.h"

CGuiLayout	cMainMenu;
float		alpha = 0;
int			lastimg = -1;

enum {
	mm_LocalPlay=0,
	mm_NetPlay,
	mm_PlayerProfiles,
	mm_LevelEditor,
	mm_Options,
	mm_Quit
};

///////////////////
// Initialize the main menu
void Menu_MainInitialize(void)
{
	int i;
	assert(tMenu);
	tMenu->iMenuRunning = true;
	tMenu->iMenuType = MNU_MAIN;

	// Create the buffer
	assert(tMenu->bmpBuffer);
	DrawImage(tMenu->bmpBuffer,tMenu->bmpMainBack_wob,0,0);
	DrawImage(tMenu->bmpBuffer,tMenu->bmpLieroXtreme, 320 - tMenu->bmpLieroXtreme->w/2, 10);
	if (tMenu->tFrontendInfo.bPageBoxes)
		Menu_DrawBox(tMenu->bmpBuffer, 15,130, 625, 465);

	Menu_RedrawMouse(true);

	alpha = 0;
	lastimg = -1;

	// Menu buttons
	int titleheight = tMenu->bmpMainTitles->h/((mm_Quit-mm_LocalPlay)*2);
	for(i=mm_LocalPlay;i<mm_Quit;i++)
		cMainMenu.Add( new CTitleButton(i, tMenu->bmpMainTitles), i, tMenu->tFrontendInfo.iMainTitlesLeft, tMenu->tFrontendInfo.iMainTitlesTop+i*(titleheight+tMenu->tFrontendInfo.iMainTitlesSpacing), tMenu->bmpMainTitles->w, titleheight);

	// Quit
	cMainMenu.Add( new CButton(BUT_QUIT, tMenu->bmpButtons), mm_Quit, 25,440, 50,15);
}

///////////////////
// Main menu frame
void Menu_MainFrame(void)
{
	gui_event_t *ev = NULL;

	//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpBuffer, 50,160, 50,160, 320,290);
	//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpBuffer, 20,430, 20,430, 60,40);

	// Process the buttons
#ifdef WITH_MEDIAPLAYER
	if (!cMediaPlayer.GetDrawPlayer())
#endif
		ev = cMainMenu.Process();
	cMainMenu.Draw(tMenu->bmpScreen);

	int mouseover = false;
	int img = lastimg;

	if(ev) {

		switch(ev->iControlID) {

			// local
			case mm_LocalPlay:
                mouseover = true;
                img=0;
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_LocalInitialize();
				    return;
                }
				break;

			// Network
			case mm_NetPlay:
                mouseover = true;
                img=1;
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_NetInitialize();
				    return;
                }
				break;

			// Player
			case mm_PlayerProfiles:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_PlayerInitialize();
				    return;
                }
				break;

			// Level editor
			case mm_LevelEditor:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
                    PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_MapEdInitialize();
				    return;
                }
				break;

			// Options
			case mm_Options:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_OptionsInitialize();
				    return;
                }
				break;

            // Quit
			case mm_Quit:
                if( ev->iEventMsg == BTN_MOUSEUP ) {
			        PlaySoundSample(sfxGeneral.smpClick);

                    cMainMenu.Draw(tMenu->bmpBuffer);

                    if( Menu_MessageBox(GetGameName(),"Quit OpenLieroX?", LMB_YESNO) == MBR_YES ) {
					    tMenu->iMenuRunning = false;
					    cMainMenu.Shutdown();
				    } else {

					    // Create the buffer
					    DrawImage(tMenu->bmpBuffer,tMenu->bmpMainBack_wob,0,0);
						if (tMenu->tFrontendInfo.bPageBoxes)
							Menu_DrawBox(tMenu->bmpBuffer, 15,130, 625, 465);
					    DrawImage(tMenu->bmpBuffer,tMenu->bmpLieroXtreme, 320 - tMenu->bmpLieroXtreme->w/2, 10);
					    Menu_RedrawMouse(true);
				    }
				    return;
                }
                break;
		}
	}

	if(mouseover) {
		alpha += tLX->fDeltaTime*5;
		alpha = MIN(1.0f,alpha);
	} else {
		alpha -= tLX->fDeltaTime*5;
		alpha = MAX(0.0f,alpha);
	}

	if(alpha) {

		DrawImageAdv(tMenu->bmpScreen,tMenu->bmpBuffer, 410,260, 410,260, 200,64);

//		int y = 640 - (int)(alpha * 10.0f)*64;  // TODO: not used

		switch(img) {
			case 0:
				//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpMainLocal, 0,y, 410, 260, tMenu->bmpMainLocal->w,64);
				break;
			case 1:
				//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpMainNet, 0,y, 410, 260, tMenu->bmpMainNet->w,64);
				break;
		}
		lastimg = img;
	}

	// Credits

	static const std::string credits1 = "  " + GetGameName() + " v" + LX_VERSION;

	static const std::string credits2 = std::string("- Original code by Jason Boettcher\n") +
										std::string("- Ported and enhanced by\n") +
										std::string("  Karel Petránek and Albert Zeyer\n") +
										std::string("- Supported by the [RIP] clan\n" +
										//std::string("- Enhanced by FilE\n" + // TODO: include this, if he join the team :)
										tMenu->tFrontendInfo.sFrontendCredits
										);

	//
	// Draw the version number
	//

	// Set special spacing for credits
	int orig_spacing = tLX->cFont.GetVSpacing();
	tLX->cFont.SetVSpacing(tMenu->tFrontendInfo.iCreditsSpacing);

	int x = tMenu->tFrontendInfo.iCreditsLeft;
	int y = tMenu->tFrontendInfo.iCreditsTop;
	static int w = 0;
	if (!w)
		w = MAX(tLX->cFont.GetWidth(credits1), tLX->cFont.GetWidth(credits2)) + 4;

	static int h = 0;
	if (!h)
		h = tLX->cFont.GetHeight() + tLX->cFont.GetHeight(credits2) + 4;

	Menu_redrawBufferRect(x, y, w, h);
	tLX->cFont.Draw(tMenu->bmpScreen, x, y, tLX->clCredits1, credits1);
	tLX->cFont.Draw(tMenu->bmpScreen, x, y + tLX->cFont.GetHeight(), tLX->clCredits2, credits2);

	// Restore the original spacing
	tLX->cFont.SetVSpacing(orig_spacing);

	// Draw the mouse
	DrawCursor(tMenu->bmpScreen);
}

///////////////////
// Shutdown the main menu
void Menu_MainShutdown(void)
{
	cMainMenu.Shutdown();
}
<commit_msg><commit_after>/////////////////////////////////////////
//
//             OpenLieroX
//
// code under LGPL, based on JasonBs work,
// enhanced by Dark Charlie and Albert Zeyer
//
//
/////////////////////////////////////////

// Main menu
// Created 30/6/02
// Jason Boettcher

#include <assert.h>

#include "LieroX.h"
#include "AuxLib.h"
#include "Graphics.h"
#include "Menu.h"
#include "GfxPrimitives.h"

CGuiLayout	cMainMenu;
float		alpha = 0;
int			lastimg = -1;

enum {
	mm_LocalPlay=0,
	mm_NetPlay,
	mm_PlayerProfiles,
	mm_LevelEditor,
	mm_Options,
	mm_Quit
};

///////////////////
// Initialize the main menu
void Menu_MainInitialize(void)
{
	int i;
	assert(tMenu);
	tMenu->iMenuRunning = true;
	tMenu->iMenuType = MNU_MAIN;

	// Create the buffer
	assert(tMenu->bmpBuffer);
	DrawImage(tMenu->bmpBuffer,tMenu->bmpMainBack_wob,0,0);
	DrawImage(tMenu->bmpBuffer,tMenu->bmpLieroXtreme, 320 - tMenu->bmpLieroXtreme->w/2, 10);
	if (tMenu->tFrontendInfo.bPageBoxes)
		Menu_DrawBox(tMenu->bmpBuffer, 15,130, 625, 465);

	Menu_RedrawMouse(true);

	alpha = 0;
	lastimg = -1;

	// Menu buttons
	int titleheight = tMenu->bmpMainTitles->h/((mm_Quit-mm_LocalPlay)*2);
	for(i=mm_LocalPlay;i<mm_Quit;i++)
		cMainMenu.Add( new CTitleButton(i, tMenu->bmpMainTitles), i, tMenu->tFrontendInfo.iMainTitlesLeft, tMenu->tFrontendInfo.iMainTitlesTop+i*(titleheight+tMenu->tFrontendInfo.iMainTitlesSpacing), tMenu->bmpMainTitles->w, titleheight);

	// Quit
	cMainMenu.Add( new CButton(BUT_QUIT, tMenu->bmpButtons), mm_Quit, 25,440, 50,15);
}

///////////////////
// Main menu frame
void Menu_MainFrame(void)
{
	gui_event_t *ev = NULL;

	//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpBuffer, 50,160, 50,160, 320,290);
	//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpBuffer, 20,430, 20,430, 60,40);

	// Process the buttons
#ifdef WITH_MEDIAPLAYER
	if (!cMediaPlayer.GetDrawPlayer())
#endif
		ev = cMainMenu.Process();
	cMainMenu.Draw(tMenu->bmpScreen);

	int mouseover = false;
	int img = lastimg;

	if(ev) {

		switch(ev->iControlID) {

			// local
			case mm_LocalPlay:
                mouseover = true;
                img=0;
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_LocalInitialize();
				    return;
                }
				break;

			// Network
			case mm_NetPlay:
                mouseover = true;
                img=1;
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_NetInitialize();
				    return;
                }
				break;

			// Player
			case mm_PlayerProfiles:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_PlayerInitialize();
				    return;
                }
				break;

			// Level editor
			case mm_LevelEditor:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
                    PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_MapEdInitialize();
				    return;
                }
				break;

			// Options
			case mm_Options:
                if( ev->iEventMsg == TBT_MOUSEUP ) {
					PlaySoundSample(sfxGeneral.smpClick);
				    cMainMenu.Shutdown();
				    Menu_OptionsInitialize();
				    return;
                }
				break;

            // Quit
			case mm_Quit:
                if( ev->iEventMsg == BTN_MOUSEUP ) {
			        PlaySoundSample(sfxGeneral.smpClick);

                    cMainMenu.Draw(tMenu->bmpBuffer);

                    if( Menu_MessageBox(GetGameName(),"Quit OpenLieroX?", LMB_YESNO) == MBR_YES ) {
					    tMenu->iMenuRunning = false;
					    cMainMenu.Shutdown();
				    } else {

					    // Create the buffer
					    DrawImage(tMenu->bmpBuffer,tMenu->bmpMainBack_wob,0,0);
						if (tMenu->tFrontendInfo.bPageBoxes)
							Menu_DrawBox(tMenu->bmpBuffer, 15,130, 625, 465);
					    DrawImage(tMenu->bmpBuffer,tMenu->bmpLieroXtreme, 320 - tMenu->bmpLieroXtreme->w/2, 10);
					    Menu_RedrawMouse(true);
				    }
				    return;
                }
                break;
		}
	}

	if(mouseover) {
		alpha += tLX->fDeltaTime*5;
		alpha = MIN(1.0f,alpha);
	} else {
		alpha -= tLX->fDeltaTime*5;
		alpha = MAX(0.0f,alpha);
	}

	if(alpha) {

		DrawImageAdv(tMenu->bmpScreen,tMenu->bmpBuffer, 410,260, 410,260, 200,64);

//		int y = 640 - (int)(alpha * 10.0f)*64;  // TODO: not used

		switch(img) {
			case 0:
				//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpMainLocal, 0,y, 410, 260, tMenu->bmpMainLocal->w,64);
				break;
			case 1:
				//DrawImageAdv(tMenu->bmpScreen, tMenu->bmpMainNet, 0,y, 410, 260, tMenu->bmpMainNet->w,64);
				break;
		}
		lastimg = img;
	}

	// Credits

	static const std::string credits1 = "  " + GetGameName() + " v" + LX_VERSION;

	static const std::string credits2 = std::string("- Original code by Jason Boettcher\n") +
										std::string("- Ported and enhanced by\n") +
										std::string("  Karel Petránek and Albert Zeyer\n") +
										std::string("- Supported by the [RIP] clan\n" +
										//std::string("- Enhanced by FilE\n" + // TODO: include this, if he join the team :)
										std::string("- Enhanced by Martin Griffin\n") +
										tMenu->tFrontendInfo.sFrontendCredits
										);

	//
	// Draw the version number
	//

	// Set special spacing for credits
	int orig_spacing = tLX->cFont.GetVSpacing();
	tLX->cFont.SetVSpacing(tMenu->tFrontendInfo.iCreditsSpacing);

	int x = tMenu->tFrontendInfo.iCreditsLeft;
	int y = tMenu->tFrontendInfo.iCreditsTop;
	static int w = 0;
	if (!w)
		w = MAX(tLX->cFont.GetWidth(credits1), tLX->cFont.GetWidth(credits2)) + 4;

	static int h = 0;
	if (!h)
		h = tLX->cFont.GetHeight() + tLX->cFont.GetHeight(credits2) + 4;

	Menu_redrawBufferRect(x, y, w, h);
	tLX->cFont.Draw(tMenu->bmpScreen, x, y, tLX->clCredits1, credits1);
	tLX->cFont.Draw(tMenu->bmpScreen, x, y + tLX->cFont.GetHeight(), tLX->clCredits2, credits2);

	// Restore the original spacing
	tLX->cFont.SetVSpacing(orig_spacing);

	// Draw the mouse
	DrawCursor(tMenu->bmpScreen);
}

///////////////////
// Shutdown the main menu
void Menu_MainShutdown(void)
{
	cMainMenu.Shutdown();
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "s60devicerunconfigurationwidget.h"
#include "s60devicerunconfiguration.h"

#include <utils/debuggerlanguagechooser.h>
#include <utils/detailswidget.h>

#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QFormLayout>

namespace Qt4ProjectManager {
namespace Internal {

S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
            S60DeviceRunConfiguration *runConfiguration,
            QWidget *parent)
    : QWidget(parent),
    m_runConfiguration(runConfiguration),
    m_detailsWidget(new Utils::DetailsWidget),
    m_argumentsLineEdit(new QLineEdit(m_runConfiguration->commandLineArguments()))
{
    m_detailsWidget->setState(Utils::DetailsWidget::NoSummary);
    QVBoxLayout *mainBoxLayout = new QVBoxLayout();
    mainBoxLayout->setMargin(0);

    QHBoxLayout *hl = new QHBoxLayout();
    hl->addStretch();
    m_disabledIcon = new QLabel(this);
    m_disabledIcon->setPixmap(QPixmap(QString::fromUtf8(":/projectexplorer/images/compile_warning.png")));
    hl->addWidget(m_disabledIcon);
    m_disabledReason = new QLabel(this);
    m_disabledReason->setVisible(false);
    hl->addWidget(m_disabledReason);
    hl->addStretch();
    mainBoxLayout->addLayout(hl);

    setLayout(mainBoxLayout);
    mainBoxLayout->addWidget(m_detailsWidget);
    QWidget *detailsContainer = new QWidget;
    m_detailsWidget->setWidget(detailsContainer);

    QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
    detailsBoxLayout->setMargin(0);
    detailsContainer->setLayout(detailsBoxLayout);

    QFormLayout *formLayout = new QFormLayout();
    formLayout->setMargin(0);
    detailsBoxLayout->addLayout(formLayout);
    formLayout->addRow(tr("Arguments:"), m_argumentsLineEdit);

    QLabel *debuggerLabel = new QLabel(tr("Debugger:"), this);
    debuggerLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);

    m_debuggerLanguageChooser = new Utils::DebuggerLanguageChooser(this);
    formLayout->addRow(debuggerLabel, m_debuggerLanguageChooser);

    m_debuggerLanguageChooser->setCppChecked(m_runConfiguration->useCppDebugger());
    m_debuggerLanguageChooser->setQmlChecked(m_runConfiguration->useQmlDebugger());
    m_debuggerLanguageChooser->setQmlDebugServerPort(m_runConfiguration->qmlDebugServerPort());

    connect(m_argumentsLineEdit, SIGNAL(textEdited(QString)),
            this, SLOT(argumentsEdited(QString)));

    connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)),
            this, SLOT(runConfigurationEnabledChange(bool)));

    connect(m_debuggerLanguageChooser, SIGNAL(cppLanguageToggled(bool)),
            this, SLOT(useCppDebuggerToggled(bool)));
    connect(m_debuggerLanguageChooser, SIGNAL(qmlLanguageToggled(bool)),
            this, SLOT(useQmlDebuggerToggled(bool)));
    connect(m_debuggerLanguageChooser, SIGNAL(qmlDebugServerPortChanged(uint)),
            this, SLOT(qmlDebugServerPortChanged(uint)));

    runConfigurationEnabledChange(m_runConfiguration->isEnabled());
}

void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
{
    m_runConfiguration->setCommandLineArguments(text.trimmed());
}

void S60DeviceRunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
{
    m_detailsWidget->setEnabled(enabled);
    m_disabledIcon->setVisible(!enabled);
    m_disabledReason->setVisible(!enabled);
    m_disabledReason->setText(m_runConfiguration->disabledReason());
}

void S60DeviceRunConfigurationWidget::useCppDebuggerToggled(bool enabled)
{
    m_runConfiguration->setUseCppDebugger(enabled);
}

void S60DeviceRunConfigurationWidget::useQmlDebuggerToggled(bool enabled)
{
    m_runConfiguration->setUseQmlDebugger(enabled);
}

void S60DeviceRunConfigurationWidget::qmlDebugServerPortChanged(uint port)
{
    m_runConfiguration->setQmlDebugServerPort(port);
}

} // namespace Internal
} // namespace Qt4ProjectManager
<commit_msg>QmlDebugging: Enable help link for S60RunConfig<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "s60devicerunconfigurationwidget.h"
#include "s60devicerunconfiguration.h"

#include <utils/debuggerlanguagechooser.h>
#include <utils/detailswidget.h>

#include <coreplugin/helpmanager.h>

#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QFormLayout>

namespace Qt4ProjectManager {
namespace Internal {

S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
            S60DeviceRunConfiguration *runConfiguration,
            QWidget *parent)
    : QWidget(parent),
    m_runConfiguration(runConfiguration),
    m_detailsWidget(new Utils::DetailsWidget),
    m_argumentsLineEdit(new QLineEdit(m_runConfiguration->commandLineArguments()))
{
    m_detailsWidget->setState(Utils::DetailsWidget::NoSummary);
    QVBoxLayout *mainBoxLayout = new QVBoxLayout();
    mainBoxLayout->setMargin(0);

    QHBoxLayout *hl = new QHBoxLayout();
    hl->addStretch();
    m_disabledIcon = new QLabel(this);
    m_disabledIcon->setPixmap(QPixmap(QString::fromUtf8(":/projectexplorer/images/compile_warning.png")));
    hl->addWidget(m_disabledIcon);
    m_disabledReason = new QLabel(this);
    m_disabledReason->setVisible(false);
    hl->addWidget(m_disabledReason);
    hl->addStretch();
    mainBoxLayout->addLayout(hl);

    setLayout(mainBoxLayout);
    mainBoxLayout->addWidget(m_detailsWidget);
    QWidget *detailsContainer = new QWidget;
    m_detailsWidget->setWidget(detailsContainer);

    QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
    detailsBoxLayout->setMargin(0);
    detailsContainer->setLayout(detailsBoxLayout);

    QFormLayout *formLayout = new QFormLayout();
    formLayout->setMargin(0);
    detailsBoxLayout->addLayout(formLayout);
    formLayout->addRow(tr("Arguments:"), m_argumentsLineEdit);

    QLabel *debuggerLabel = new QLabel(tr("Debugger:"), this);
    debuggerLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);

    m_debuggerLanguageChooser = new Utils::DebuggerLanguageChooser(this);
    formLayout->addRow(debuggerLabel, m_debuggerLanguageChooser);

    m_debuggerLanguageChooser->setCppChecked(m_runConfiguration->useCppDebugger());
    m_debuggerLanguageChooser->setQmlChecked(m_runConfiguration->useQmlDebugger());
    m_debuggerLanguageChooser->setQmlDebugServerPort(m_runConfiguration->qmlDebugServerPort());

    connect(m_argumentsLineEdit, SIGNAL(textEdited(QString)),
            this, SLOT(argumentsEdited(QString)));

    connect(m_runConfiguration, SIGNAL(isEnabledChanged(bool)),
            this, SLOT(runConfigurationEnabledChange(bool)));

    connect(m_debuggerLanguageChooser, SIGNAL(cppLanguageToggled(bool)),
            this, SLOT(useCppDebuggerToggled(bool)));
    connect(m_debuggerLanguageChooser, SIGNAL(qmlLanguageToggled(bool)),
            this, SLOT(useQmlDebuggerToggled(bool)));
    connect(m_debuggerLanguageChooser, SIGNAL(qmlDebugServerPortChanged(uint)),
            this, SLOT(qmlDebugServerPortChanged(uint)));
    connect(m_debuggerLanguageChooser, SIGNAL(openHelpUrl(QString)),
            Core::HelpManager::instance(), SLOT(handleHelpRequest(QString)));

    runConfigurationEnabledChange(m_runConfiguration->isEnabled());
}

void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
{
    m_runConfiguration->setCommandLineArguments(text.trimmed());
}

void S60DeviceRunConfigurationWidget::runConfigurationEnabledChange(bool enabled)
{
    m_detailsWidget->setEnabled(enabled);
    m_disabledIcon->setVisible(!enabled);
    m_disabledReason->setVisible(!enabled);
    m_disabledReason->setText(m_runConfiguration->disabledReason());
}

void S60DeviceRunConfigurationWidget::useCppDebuggerToggled(bool enabled)
{
    m_runConfiguration->setUseCppDebugger(enabled);
}

void S60DeviceRunConfigurationWidget::useQmlDebuggerToggled(bool enabled)
{
    m_runConfiguration->setUseQmlDebugger(enabled);
}

void S60DeviceRunConfigurationWidget::qmlDebugServerPortChanged(uint port)
{
    m_runConfiguration->setQmlDebugServerPort(port);
}

} // namespace Internal
} // namespace Qt4ProjectManager
<|endoftext|>


<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "btree/depth_first_traversal.hpp"

#include "btree/operations.hpp"
#include "rdb_protocol/profile.hpp"

#if SLICE_ALT
using namespace alt;  // RSI
#endif

/* Returns `true` if we reached the end of the subtree or range, and `false` if
`cb->handle_value()` returned `false`. */
#if SLICE_ALT
bool btree_depth_first_traversal(btree_slice_t *slice,
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction);
#else
bool btree_depth_first_traversal(btree_slice_t *slice, transaction_t *transaction,
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction);
#endif

#if SLICE_ALT
bool btree_depth_first_traversal(btree_slice_t *slice, superblock_t *superblock,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction) {
#else
bool btree_depth_first_traversal(btree_slice_t *slice, transaction_t *transaction, superblock_t *superblock, const key_range_t &range, depth_first_traversal_callback_t *cb, direction_t direction) {
#endif
    block_id_t root_block_id = superblock->get_root_block_id();
    if (root_block_id == NULL_BLOCK_ID) {
        superblock->release();
        return true;
    } else {
        counted_t<counted_buf_lock_t> root_block;
        {
            // RSI: This profile information might be wrong, because before it seems
            // to measure how long it takes to acquire the block, but now (I think)
            // it just measures how long it takes to "get in line" i.e. no time at
            // all.
            profile::starter_t starter("Acquire block for read.", cb->get_trace());
#if SLICE_ALT
            root_block = make_counted<counted_buf_lock_t>(superblock->expose_buf(),
                                                          root_block_id,
                                                          alt_access_t::read);
#else
            root_block = make_counted<counted_buf_lock_t>(transaction, root_block_id,
                                                          rwi_read);
#endif
        }
        superblock->release();
#if SLICE_ALT
        return btree_depth_first_traversal(slice, std::move(root_block), range, cb,
                                           direction);
#else
        return btree_depth_first_traversal(slice, transaction, std::move(root_block), range, cb, direction);
#endif
    }
}

bool btree_depth_first_traversal(btree_slice_t *slice, transaction_t *transaction,
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction) {
#if SLICE_ALT
    alt_buf_read_t read(block.get());
    const node_t *node = static_cast<const node_t *>(read.get_data_read());
#else
    const node_t *node = static_cast<const node_t *>(block->get_data_read());
#endif
    if (node::is_internal(node)) {
        const internal_node_t *inode = reinterpret_cast<const internal_node_t *>(node);
        int start_index = internal_node::get_offset_index(inode, range.left.btree_key());
        int end_index;
        if (range.right.unbounded) {
            end_index = inode->npairs;
        } else {
            store_key_t r = range.right.key;
            r.decrement();
            end_index = internal_node::get_offset_index(inode, r.btree_key()) + 1;
        }
        for (int i = 0; i < end_index - start_index; ++i) {
            int true_index = (direction == FORWARD ? start_index + i : (end_index - 1) - i);
            const btree_internal_pair *pair = internal_node::get_pair_by_index(inode, true_index);
            counted_t<counted_buf_lock_t> lock;
            {
                profile::starter_t starter("Acquire block for read.", cb->get_trace());
#if SLICE_ALT
                lock = make_counted<counted_buf_lock_t>(block.get(), pair->lnode,
                                                        alt_access_t::read);
#else
                lock = make_counted<counted_buf_lock_t>(transaction, pair->lnode,
                                                        rwi_read);
#endif
            }
            if (!btree_depth_first_traversal(slice, transaction, std::move(lock),
                                             range, cb, direction)) {
                return false;
            }
        }
        return true;
    } else {
        const leaf_node_t *lnode = reinterpret_cast<const leaf_node_t *>(node);
        const btree_key_t *key;

        if (direction == FORWARD) {
            for (auto it = leaf::inclusive_lower_bound(range.left.btree_key(), *lnode);
                 it != leaf::end(*lnode); ++it) {
                key = (*it).first;
                if (!range.right.unbounded &&
                    btree_key_cmp(key, range.right.key.btree_key()) >= 0) {
                    break;
                }
                if (!cb->handle_pair(scoped_key_value_t(key, (*it).second,
                                                        movable_t<counted_buf_lock_t>(block)))) {
                    return false;
                }
            }
        } else {
            leaf_node_t::reverse_iterator it;
            if (range.right.unbounded) {
                it = leaf::rbegin(*lnode);
            } else {
                it = leaf::inclusive_upper_bound(range.right.key.btree_key(), *lnode);
            }
            for (/* assignment above */; it != leaf::rend(*lnode); ++it) {
                key = (*it).first;

                if (btree_key_cmp(key, range.left.btree_key()) <= 0) {
                    break;
                }

                if (!cb->handle_pair(scoped_key_value_t(key, (*it).second,
                                                        movable_t<counted_buf_lock_t>(block)))) {
                    return false;
                }
            }
        }
        return true;
    }
}
<commit_msg>Removed alt cache linker error in depth_first_traversal.cc.<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "btree/depth_first_traversal.hpp"

#include "btree/operations.hpp"
#include "rdb_protocol/profile.hpp"

#if SLICE_ALT
using namespace alt;  // RSI
#endif

/* Returns `true` if we reached the end of the subtree or range, and `false` if
`cb->handle_value()` returned `false`. */
#if SLICE_ALT
bool btree_depth_first_traversal(btree_slice_t *slice,
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction);
#else
bool btree_depth_first_traversal(btree_slice_t *slice, transaction_t *transaction,
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction);
#endif

#if SLICE_ALT
bool btree_depth_first_traversal(btree_slice_t *slice, superblock_t *superblock,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction) {
#else
bool btree_depth_first_traversal(btree_slice_t *slice, transaction_t *transaction, superblock_t *superblock, const key_range_t &range, depth_first_traversal_callback_t *cb, direction_t direction) {
#endif
    block_id_t root_block_id = superblock->get_root_block_id();
    if (root_block_id == NULL_BLOCK_ID) {
        superblock->release();
        return true;
    } else {
        counted_t<counted_buf_lock_t> root_block;
        {
            // RSI: This profile information might be wrong, because before it seems
            // to measure how long it takes to acquire the block, but now (I think)
            // it just measures how long it takes to "get in line" i.e. no time at
            // all.
            profile::starter_t starter("Acquire block for read.", cb->get_trace());
#if SLICE_ALT
            root_block = make_counted<counted_buf_lock_t>(superblock->expose_buf(),
                                                          root_block_id,
                                                          alt_access_t::read);
#else
            root_block = make_counted<counted_buf_lock_t>(transaction, root_block_id,
                                                          rwi_read);
#endif
        }
        superblock->release();
#if SLICE_ALT
        return btree_depth_first_traversal(slice, std::move(root_block), range, cb,
                                           direction);
#else
        return btree_depth_first_traversal(slice, transaction, std::move(root_block), range, cb, direction);
#endif
    }
}

bool btree_depth_first_traversal(btree_slice_t *slice,
#if !SLICE_ALT
                                 transaction_t *transaction,
#endif
                                 counted_t<counted_buf_lock_t> block,
                                 const key_range_t &range,
                                 depth_first_traversal_callback_t *cb,
                                 direction_t direction) {
#if SLICE_ALT
    alt_buf_read_t read(block.get());
    const node_t *node = static_cast<const node_t *>(read.get_data_read());
#else
    const node_t *node = static_cast<const node_t *>(block->get_data_read());
#endif
    if (node::is_internal(node)) {
        const internal_node_t *inode = reinterpret_cast<const internal_node_t *>(node);
        int start_index = internal_node::get_offset_index(inode, range.left.btree_key());
        int end_index;
        if (range.right.unbounded) {
            end_index = inode->npairs;
        } else {
            store_key_t r = range.right.key;
            r.decrement();
            end_index = internal_node::get_offset_index(inode, r.btree_key()) + 1;
        }
        for (int i = 0; i < end_index - start_index; ++i) {
            int true_index = (direction == FORWARD ? start_index + i : (end_index - 1) - i);
            const btree_internal_pair *pair = internal_node::get_pair_by_index(inode, true_index);
            counted_t<counted_buf_lock_t> lock;
            {
                profile::starter_t starter("Acquire block for read.", cb->get_trace());
#if SLICE_ALT
                lock = make_counted<counted_buf_lock_t>(block.get(), pair->lnode,
                                                        alt_access_t::read);
#else
                lock = make_counted<counted_buf_lock_t>(transaction, pair->lnode,
                                                        rwi_read);
#endif
            }
            if (!btree_depth_first_traversal(slice,
#if !SLICE_ALT
                                             transaction,
#endif
                                             std::move(lock),
                                             range, cb, direction)) {
                return false;
            }
        }
        return true;
    } else {
        const leaf_node_t *lnode = reinterpret_cast<const leaf_node_t *>(node);
        const btree_key_t *key;

        if (direction == FORWARD) {
            for (auto it = leaf::inclusive_lower_bound(range.left.btree_key(), *lnode);
                 it != leaf::end(*lnode); ++it) {
                key = (*it).first;
                if (!range.right.unbounded &&
                    btree_key_cmp(key, range.right.key.btree_key()) >= 0) {
                    break;
                }
                if (!cb->handle_pair(scoped_key_value_t(key, (*it).second,
                                                        movable_t<counted_buf_lock_t>(block)))) {
                    return false;
                }
            }
        } else {
            leaf_node_t::reverse_iterator it;
            if (range.right.unbounded) {
                it = leaf::rbegin(*lnode);
            } else {
                it = leaf::inclusive_upper_bound(range.right.key.btree_key(), *lnode);
            }
            for (/* assignment above */; it != leaf::rend(*lnode); ++it) {
                key = (*it).first;

                if (btree_key_cmp(key, range.left.btree_key()) <= 0) {
                    break;
                }

                if (!cb->handle_pair(scoped_key_value_t(key, (*it).second,
                                                        movable_t<counted_buf_lock_t>(block)))) {
                    return false;
                }
            }
        }
        return true;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2007-2010 Paul Hodge. All rights reserved.

#include <circa.h>

namespace circa {
namespace any_true_function {

    void evaluate(EvalContext*, Term* caller)
    {
        Branch& input = as_branch(caller->input(0));

        bool result = false;
        for (int i=0; i < input.length(); i++)
            if (input[i]->asBool()) {
                result = true;
                break;
            }

        set_bool(caller, result);
    }

    void setup(Branch& kernel)
    {
        import_function(kernel, evaluate, "any_true(List l) -> bool;"
                "'Return whether any of the items in l are true' end");
    }
}
} // namespace circa
<commit_msg>any_true is now list-generic<commit_after>// Copyright (c) 2007-2010 Paul Hodge. All rights reserved.

#include <circa.h>

namespace circa {
namespace any_true_function {

    void evaluate(EvalContext*, Term* caller)
    {
        TaggedValue* input = caller->input(0);

        int numElements = input->numElements();

        bool result = false;
        for (int i=0; i < numElements; i++)
            if (as_bool((*input)[i])) {
                result = true;
                break;
            }

        set_bool(caller, result);
    }

    void setup(Branch& kernel)
    {
        import_function(kernel, evaluate, "any_true(List l) -> bool;"
                "'Return whether any of the items in l are true' end");
    }
}
} // namespace circa
<|endoftext|>