<commit_before>#ifndef AMGCL_UTIL_HPP
#define AMGCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2018 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   amgcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Various utilities.
 */

#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <complex>
#include <limits>
#include <stdexcept>
#include <cstddef>

// If asked explicitly, or if boost is available, enable
// using boost::propert_tree::ptree as amgcl parameters:
#ifndef AMGCL_NO_BOOST
#  include <boost/property_tree/ptree.hpp>
#endif

/* Performance measurement macros
 *
 * If AMGCL_PROFILING macro is defined at compilation, then AMGCL_TIC(name) and
 * AMGCL_TOC(name) macros correspond to prof.tic(name) and prof.toc(name).
 * amgcl::prof should be an instance of amgcl::profiler<> defined in a user
 * code similar to:
 * \code
 * namespace amgcl { profiler<> prof; }
 * \endcode
 * If AMGCL_PROFILING is undefined, then AMGCL_TIC and AMGCL_TOC are noop macros.
 */
#ifdef AMGCL_PROFILING
#  include <amgcl/profiler.hpp>
#  define AMGCL_TIC(name) amgcl::prof.tic(name);
#  define AMGCL_TOC(name) amgcl::prof.toc(name);
namespace amgcl { extern profiler<> prof; }
#else
#  ifndef AMGCL_TIC
#    define AMGCL_TIC(name)
#  endif
#  ifndef AMGCL_TOC
#    define AMGCL_TOC(name)
#  endif
#endif

#define AMGCL_DEBUG_SHOW(x)                                                    \
    std::cout << std::setw(20) << #x << ": "                                   \
              << std::setw(15) << std::setprecision(8) << std::scientific      \
              << (x) << std::endl

namespace amgcl {

/// Throws \p message if \p condition is not true.
template <class Condition, class Message>
void precondition(const Condition &condition, const Message &message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

#ifndef AMGCL_NO_BOOST

#define AMGCL_PARAMS_IMPORT_VALUE(p, name)                                     \
    name( p.get(#name, params().name) )

#define AMGCL_PARAMS_IMPORT_CHILD(p, name)                                     \
    name( p.get_child(#name, amgcl::detail::empty_ptree()) )

#define AMGCL_PARAMS_EXPORT_VALUE(p, path, name)                               \
    p.put(std::string(path) + #name, name)

#define AMGCL_PARAMS_EXPORT_CHILD(p, path, name)                               \
    name.get(p, std::string(path) + #name + ".")

// Missing parameter action
#ifndef AMGCL_PARAM_MISSING
#  define AMGCL_PARAM_MISSING(name) (void)0
#endif

// Unknown parameter action
#ifndef AMGCL_PARAM_UNKNOWN
#  define AMGCL_PARAM_UNKNOWN(name)                                            \
      std::cerr << "AMGCL WARNING: unknown parameter " << name << std::endl
#endif

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names,
        const std::set<std::string> &opt_names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &n : opt_names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first) && !opt_names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

// Put parameter in form "key=value" into a boost::property_tree::ptree
inline void put(boost::property_tree::ptree &p, const std::string &param) {
    size_t eq_pos = param.find('=');
    if (eq_pos == std::string::npos)
        throw std::invalid_argument("param in amgcl::put() should have \"key=value\" format!");
    p.put(param.substr(0, eq_pos), param.substr(eq_pos + 1));
}

#endif

namespace detail {

#ifndef AMGCL_NO_BOOST
inline const boost::property_tree::ptree& empty_ptree() {
    static const boost::property_tree::ptree p;
    return p;
}
#endif

struct empty_params {
    empty_params() {}

#ifndef AMGCL_NO_BOOST
    empty_params(const boost::property_tree::ptree &p) {
        for(const auto &v : p) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
    void get(boost::property_tree::ptree&, const std::string&) const {}
#endif
};

} // namespace detail

// N-dimensional dense matrix
template <class T, int N>
class multi_array {
    static_assert(N > 0, "Wrong number of dimensions");

    public:
        template <class... I>
        multi_array(I... n) {
            static_assert(sizeof...(I) == N, "Wrong number of dimensions");
            buf.resize(init(n...));
        }

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

        int stride(int i) const {
            return strides[i];
        }

        template <class... I>
        T operator()(I... i) const {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        template <class... I>
        T& operator()(I... i) {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        const T* data() const {
            return buf.data();
        }

        T* data() {
            return buf.data();
        }
    private:
        std::array<int, N> strides;
        std::vector<T>  buf;

        template <class... I>
        int index(int i, I... tail) const {
            return strides[N - sizeof...(I) - 1] * i + index(tail...);
        }

        int index(int i) const {
            return strides[N-1] * i;
        }

        template <class... I>
        int init(int i, I... tail) {
            int size = init(tail...);
            strides[N - sizeof...(I) - 1] = size;
            return i * size;
        }

        int init(int i) {
            strides[N-1] = 1;
            return i;
        }
};

template <class T>
class circular_buffer {
    public:
        circular_buffer(size_t n) : start(0) {
            buf.reserve(n);
        }

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

        void push_back(const T &v) {
            if (buf.size() < buf.capacity()) {
                buf.push_back(v);
            } else {
                buf[start] = v;
                start = (start + 1) % buf.capacity();
            }
        }

        const T& operator[](size_t i) const {
            return buf[(start + i) % buf.capacity()];
        }

        T& operator[](size_t i) {
            return buf[(start + i) % buf.capacity()];
        }

        void clear() {
            buf.clear();
            start = 0;
        }

    private:
        size_t start;
        std::vector<T> buf;
};

namespace detail {

template <class T>
T eps(size_t n) {
    return 2 * std::numeric_limits<T>::epsilon() * n;
}

} // namespace detail

template <class T> struct is_complex : std::false_type {};
template <class T> struct is_complex< std::complex<T> > : std::true_type {};

inline std::string human_readable_memory(size_t bytes) {
    static const char *suffix[] = {"B", "K", "M", "G", "T"};

    int i = 0;
    double m = bytes;
    for(; i < 4 && m >= 1024; ++i, m /= 1024);

    std::ostringstream s;
    s << std::fixed << std::setprecision(2) << m << " " << suffix[i];
    return s.str();
}

} // namespace amgcl

namespace std {

// Read pointers from input streams.
// This allows to exchange pointers through boost::property_tree::ptree.
template <class T>
inline istream& operator>>(istream &is, T* &ptr) {
    std::ios_base::fmtflags ff(is.flags());

    size_t val;
    is >> std::hex >> val;

    ptr = reinterpret_cast<T*>(val);

    is.flags(ff);
    return is;
}

} // namespace std

#endif
<commit_msg>Fix a type mismatch warning<commit_after>#ifndef AMGCL_UTIL_HPP
#define AMGCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2018 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   amgcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  Various utilities.
 */

#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <complex>
#include <limits>
#include <stdexcept>
#include <cstddef>

// If asked explicitly, or if boost is available, enable
// using boost::propert_tree::ptree as amgcl parameters:
#ifndef AMGCL_NO_BOOST
#  include <boost/property_tree/ptree.hpp>
#endif

/* Performance measurement macros
 *
 * If AMGCL_PROFILING macro is defined at compilation, then AMGCL_TIC(name) and
 * AMGCL_TOC(name) macros correspond to prof.tic(name) and prof.toc(name).
 * amgcl::prof should be an instance of amgcl::profiler<> defined in a user
 * code similar to:
 * \code
 * namespace amgcl { profiler<> prof; }
 * \endcode
 * If AMGCL_PROFILING is undefined, then AMGCL_TIC and AMGCL_TOC are noop macros.
 */
#ifdef AMGCL_PROFILING
#  include <amgcl/profiler.hpp>
#  define AMGCL_TIC(name) amgcl::prof.tic(name);
#  define AMGCL_TOC(name) amgcl::prof.toc(name);
namespace amgcl { extern profiler<> prof; }
#else
#  ifndef AMGCL_TIC
#    define AMGCL_TIC(name)
#  endif
#  ifndef AMGCL_TOC
#    define AMGCL_TOC(name)
#  endif
#endif

#define AMGCL_DEBUG_SHOW(x)                                                    \
    std::cout << std::setw(20) << #x << ": "                                   \
              << std::setw(15) << std::setprecision(8) << std::scientific      \
              << (x) << std::endl

namespace amgcl {

/// Throws \p message if \p condition is not true.
template <class Condition, class Message>
void precondition(const Condition &condition, const Message &message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

#ifndef AMGCL_NO_BOOST

#define AMGCL_PARAMS_IMPORT_VALUE(p, name)                                     \
    name( p.get(#name, params().name) )

#define AMGCL_PARAMS_IMPORT_CHILD(p, name)                                     \
    name( p.get_child(#name, amgcl::detail::empty_ptree()) )

#define AMGCL_PARAMS_EXPORT_VALUE(p, path, name)                               \
    p.put(std::string(path) + #name, name)

#define AMGCL_PARAMS_EXPORT_CHILD(p, path, name)                               \
    name.get(p, std::string(path) + #name + ".")

// Missing parameter action
#ifndef AMGCL_PARAM_MISSING
#  define AMGCL_PARAM_MISSING(name) (void)0
#endif

// Unknown parameter action
#ifndef AMGCL_PARAM_UNKNOWN
#  define AMGCL_PARAM_UNKNOWN(name)                                            \
      std::cerr << "AMGCL WARNING: unknown parameter " << name << std::endl
#endif

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

inline void check_params(
        const boost::property_tree::ptree &p,
        const std::set<std::string> &names,
        const std::set<std::string> &opt_names
        )
{
    for(const auto &n : names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &n : opt_names) {
        if (!p.count(n)) {
            AMGCL_PARAM_MISSING(n);
        }
    }
    for(const auto &v : p) {
        if (!names.count(v.first) && !opt_names.count(v.first)) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
}

// Put parameter in form "key=value" into a boost::property_tree::ptree
inline void put(boost::property_tree::ptree &p, const std::string &param) {
    size_t eq_pos = param.find('=');
    if (eq_pos == std::string::npos)
        throw std::invalid_argument("param in amgcl::put() should have \"key=value\" format!");
    p.put(param.substr(0, eq_pos), param.substr(eq_pos + 1));
}

#endif

namespace detail {

#ifndef AMGCL_NO_BOOST
inline const boost::property_tree::ptree& empty_ptree() {
    static const boost::property_tree::ptree p;
    return p;
}
#endif

struct empty_params {
    empty_params() {}

#ifndef AMGCL_NO_BOOST
    empty_params(const boost::property_tree::ptree &p) {
        for(const auto &v : p) {
            AMGCL_PARAM_UNKNOWN(v.first);
        }
    }
    void get(boost::property_tree::ptree&, const std::string&) const {}
#endif
};

} // namespace detail

// N-dimensional dense matrix
template <class T, int N>
class multi_array {
    static_assert(N > 0, "Wrong number of dimensions");

    public:
        template <class... I>
        multi_array(I... n) {
            static_assert(sizeof...(I) == N, "Wrong number of dimensions");
            buf.resize(init(n...));
        }

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

        int stride(int i) const {
            return strides[i];
        }

        template <class... I>
        T operator()(I... i) const {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        template <class... I>
        T& operator()(I... i) {
            static_assert(sizeof...(I) == N, "Wrong number of indices");
            return buf[index(i...)];
        }

        const T* data() const {
            return buf.data();
        }

        T* data() {
            return buf.data();
        }
    private:
        std::array<int, N> strides;
        std::vector<T>  buf;

        template <class... I>
        int index(int i, I... tail) const {
            return strides[N - sizeof...(I) - 1] * i + index(tail...);
        }

        int index(int i) const {
            return strides[N-1] * i;
        }

        template <class... I>
        int init(int i, I... tail) {
            int size = init(tail...);
            strides[N - sizeof...(I) - 1] = size;
            return i * size;
        }

        int init(int i) {
            strides[N-1] = 1;
            return i;
        }
};

template <class T>
class circular_buffer {
    public:
        circular_buffer(size_t n) : start(0) {
            buf.reserve(n);
        }

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

        void push_back(const T &v) {
            if (buf.size() < buf.capacity()) {
                buf.push_back(v);
            } else {
                buf[start] = v;
                start = (start + 1) % buf.capacity();
            }
        }

        const T& operator[](size_t i) const {
            return buf[(start + i) % buf.capacity()];
        }

        T& operator[](size_t i) {
            return buf[(start + i) % buf.capacity()];
        }

        void clear() {
            buf.clear();
            start = 0;
        }

    private:
        size_t start;
        std::vector<T> buf;
};

namespace detail {

template <class T>
T eps(size_t n) {
    return 2 * std::numeric_limits<T>::epsilon() * n;
}

} // namespace detail

template <class T> struct is_complex : std::false_type {};
template <class T> struct is_complex< std::complex<T> > : std::true_type {};

inline std::string human_readable_memory(size_t bytes) {
    static const char *suffix[] = {"B", "K", "M", "G", "T"};

    int i = 0;
    double m = bytes;
    for(; i < 4 && m >= 1024.0; ++i, m /= 1024.0);

    std::ostringstream s;
    s << std::fixed << std::setprecision(2) << m << " " << suffix[i];
    return s.str();
}

} // namespace amgcl

namespace std {

// Read pointers from input streams.
// This allows to exchange pointers through boost::property_tree::ptree.
template <class T>
inline istream& operator>>(istream &is, T* &ptr) {
    std::ios_base::fmtflags ff(is.flags());

    size_t val;
    is >> std::hex >> val;

    ptr = reinterpret_cast<T*>(val);

    is.flags(ff);
    return is;
}

} // namespace std

#endif
<|endoftext|>


<commit_before>
#include "accurate_intersections_approx.hpp"
#include "accurate_intersections_incprec.hpp"
#include "accurate_intersections_resultant.hpp"
#include "geometry.hpp"
#include "line.hpp"
#include "quadric.hpp"
#include "quadric_classify.hpp"
#include "timer.hpp"

#include <array>
#include <fstream>
#include <iomanip>
#include <list>
#include <random>

#include <signal.h>
#include <unistd.h>

#include "tester.hpp"

struct GlobalVars {
  bool run = true;
} globals;

void sigInt(int signum) { globals.run = false; }

template <int dim, typename fptype>
std::list<Geometry::Quadric<dim, fptype>> parseQuadrics(
    const char *fname, int *minExp, int *maxExp) {
  std::ifstream file(fname);
  if(!file.is_open()) {
    return std::list<Geometry::Quadric<dim, fptype>>();
  }
  int buf = 0;
  file >> buf;
  if(minExp != NULL) {
    *minExp = buf;
  }
  file >> buf;
  if(maxExp != NULL) {
    *maxExp = buf;
  }
  if(*minExp > 0) {
    std::cout
        << "Cannot generate a line with these exponents\n"
        << *minExp << ", " << *maxExp << "\n";
    exit(1);
  }
  std::cout << "Using " << *minExp << ", " << *maxExp
            << " as the range of exponents\n";

  using Qf = Geometry::Quadric<dim, fptype>;
  int qtypeCount[QuadricClassify::QUADT_ERRORINVALID];
  for(int i = 0; i < QuadricClassify::QUADT_ERRORINVALID;
      i++)
    qtypeCount[i] = 0;
  std::list<Qf> quads;
  int imQuads = 0;
  int numQuads = 0;
  while(!file.eof()) {
    Qf q;
    file >> q;
    QuadricClassify::QuadType type =
        QuadricClassify::classifyQuadric(q);
    if(!QuadricClassify::isImaginary(type) &&
       type != QuadricClassify::QUADT_ERROR &&
       type != QuadricClassify::QUADT_DEGENERATE &&
       type != QuadricClassify::QUADT_ERRORINVALID) {
      quads.push_back(q);
      qtypeCount[type]++;
    } else {
      std::cout << "Quadric " << numQuads
                << " is invalid, returned type "
                << QuadricClassify::QuadTypeNames[type]
                << "\n";
      imQuads++;
    }
    numQuads++;
  }
  for(int i = 0; i < QuadricClassify::QUADT_ERRORINVALID;
      i++) {
    std::cout << qtypeCount[i] << " "
              << QuadricClassify::QuadTypeNames[i] << "\n";
  }
  return quads;
}

using rngAlg = std::mt19937_64;

template <int dim, typename fptype>
using randLineGen = Geometry::Line<dim, fptype> (*)(
    rngAlg &rng, int minExp, int maxExp);

template <int dim, typename fptype>
void intersectionTest(
    std::list<Geometry::Quadric<dim, fptype>> &quads,
    std::ostream &output, const int numTests,
    randLineGen<dim, fptype> rlgf, int minExp, int maxExp,
    bool fixedSeed) {
  /* First build a scene of quadrics.
   * Then generate random lines on a disk centered at the
   * intersection of the cylinders.
   * Then sort the intersections
   * Finally validate them with a higher precision sort
   */
  using Vf = Geometry::Vector<dim, fptype>;
  using Pf = Geometry::Point<dim, fptype>;
  using Lf = Geometry::Line<dim, fptype>;

	std::random_device rd;
  rngAlg engine(rd());
  if(fixedSeed) {
    engine.seed(682185716);
  }

  const double eps = 1.52587890625e-5;

  Tester<dim, fptype,
         Geometry::IntersectionResultant<dim, fptype>>
      resultantTest(numTests, &quads, eps);

  Tester<dim, fptype, Geometry::IntersectionApproximate<
                          dim, fptype, float>>
      singleTest(numTests, &quads, eps);

  Tester<dim, fptype, Geometry::IntersectionApproximate<
                          dim, fptype, float>>
      doubleTest(numTests, &quads, eps);

  Tester<dim, fptype,
         Geometry::IntersectionIncreasedPrec<dim, fptype>>
      mpTest(numTests, &quads, eps);

  std::vector<Lf> lines;
  /* Run the tests */
  int t;
  for(t = 0; t < numTests && globals.run; t++) {
    Lf line = rlgf(engine, minExp, maxExp);
    /* Then sort the intersections */
    resultantTest.runTest(line);
    singleTest.runTest(line);
    doubleTest.runTest(line);
    mpTest.runTest(line);
    lines.push_back(line);
    singleTest.updateResults(resultantTest.getResults());
    doubleTest.updateResults(resultantTest.getResults());
    mpTest.updateResults(resultantTest.getResults());
    resultantTest.updateResults(resultantTest.getResults());
  }
  /* Output the aggregate of the results */
  output << "Singles Incorrect: "
         << singleTest.getTotalIncorrect() << "\n"
         << "Single Total Time (ns): "
         << singleTest.getTotalTime_ns() << "\n\n";
  output << "Doubles Incorrect: "
         << doubleTest.getTotalIncorrect() << "\n"
         << "Double Total Time (ns): "
         << doubleTest.getTotalTime_ns() << "\n\n";
  output << "Increased Precision Incorrect: "
         << mpTest.getTotalIncorrect() << "\n"
         << "Increased Precision Total Time (ns): "
         << mpTest.getTotalTime_ns() << "\n\n";
  output << "Resultant Total Time (ns): "
         << resultantTest.getTotalTime_ns() << "\n\n\n";
  /* Output all of the results */
  output << "Test #, Singles, Single Times (ns), Single "
            "Correct, Doubles, Double Times (ns), Double "
            "Correct, Increased Precs, MP Time (ns), MP "
            "Correct, Resultants, Resultant Time (ns), "
            "Line Dir X, Line Dir Y, Line Dir Z, "
            "Line Int X, Line Int Y, Line Int Z\n";
  for(int i = 0; i < t; i++) {
    output << i + 1 << ", ";
    printResult(singleTest.getResult(i), output);
    output << ", ";
    printResult(doubleTest.getResult(i), output);
    output << ", ";
    printResult(mpTest.getResult(i), output);
    output << ", ";
    printResult(resultantTest.getResult(i), output);
    output << ", ";
    output << lines[i].getDirection().get(0);
    output << ", ";
    output << lines[i].getDirection().get(1);
    output << ", ";
    output << lines[i].getDirection().get(2);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(0);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(1);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(2);
    output << "\n";
  }
}

void lockCPU() {
  const int numCPUs = sysconf(_SC_NPROCESSORS_ONLN);
  const int cpuSets =
      numCPUs / CPU_SETSIZE + ((numCPUs % CPU_SETSIZE) > 0);
  cpu_set_t *cpus = new cpu_set_t[cpuSets];
  const size_t cpuSize = sizeof(cpu_set_t[cpuSets]);
  sched_getaffinity(0, cpuSize, cpus);
  for(int i = 1; i < numCPUs; i++) CPU_CLR(i, cpus);
  CPU_SET(0, cpus);
  sched_setaffinity(0, cpuSize, cpus);
  delete[] cpus;
}

template <typename fptype>
bool checkExp(fptype fpVal, int minExp, int maxExp) {
  if(fpVal == fptype(0.0)) {
    return true;
  }
  GenericFP::fpconvert<fptype> *fpbits =
      reinterpret_cast<GenericFP::fpconvert<fptype> *>(
          &fpVal);
  int exponent = fpbits->exponent;
  exponent -= fpbits->centralExp;
  if(exponent < minExp || exponent > maxExp) {
    return false;
  } else {
    return true;
  }
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> defRandLine(rngAlg &rng,
                                        int minExp,
                                        int maxExp) {
  constexpr const fptype minPos = 0, maxPos = 1;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  std::uniform_real_distribution<fptype> genDir(-1.0, 1.0);
  /* First build the line */
  Geometry::Vector<dim, fptype> lineDir;
  Geometry::Vector<dim, fptype> lineInt;
  for(int i = 0; i < dim; i++) {
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genPos(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineInt.set(i, tmp);
    } while(checkExp(lineInt.get(i), minExp, maxExp) ==
            false);
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genDir(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineDir.set(i, tmp);
    } while(checkExp(lineDir.get(i), minExp, maxExp) ==
            false);
  }
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineInt);
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> nestedEllRandLine(rngAlg &rng,
                                              int minExp,
                                              int maxExp) {
  constexpr const fptype minPos = 0.0, maxPos = 1.0;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  Geometry::Vector<dim, fptype> lineInt;
  constexpr const fptype maxDeltaMag = 0.0078125;
  std::uniform_real_distribution<fptype> genDelta(
      -maxDeltaMag, maxDeltaMag);
  Geometry::Vector<dim, fptype> delta;
  for(int i = 0; i < dim; i++) {
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genPos(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineInt.set(i, tmp);
    } while(checkExp(lineInt.get(i), minExp, maxExp) ==
            false);
    delta.set(i, genDelta(rng));
  }
  /* Direct the line towards (1.0, 0.5, 0.5) + delta */
  const Geometry::Vector<dim, fptype> destination =
      Geometry::Vector<dim, fptype>({1.0, 0.5, 0.5}) +
      delta;
  Geometry::Vector<dim, fptype> lineDir =
      destination - lineInt;
  /* Fix the exponent and the mantissa to fit within our
   * bounds for correctness
   */
  int maximum = std::numeric_limits<int>::min();
  for(int i = 0; i < dim; i++) {
    int exp = 0;
    MathFuncs::MathFuncs<fptype>::frexp(lineDir.get(i),
                                        &exp);
    if(exp > maximum) {
      maximum = exp;
    }
  }
  fptype multiplier = MathFuncs::MathFuncs<fptype>::ldexp(
      1.0, maxExp - maximum);
  for(int i = 0; i < dim; i++) {
    union {
      fptype tmp;
      GenericFP::fpconvert<fptype> bitmanipulate;
    };

    tmp = lineDir.get(i) * multiplier;
    bitmanipulate.mantissa &= ~((1 << 12) - 1);
    if(MathFuncs::MathFuncs<fptype>::fabs(tmp) <
       MathFuncs::MathFuncs<fptype>::ldexp(1.0, minExp)) {
      if(MathFuncs::MathFuncs<fptype>::fabs(tmp) >
         MathFuncs::MathFuncs<fptype>::ldexp(1.0,
                                             minExp - 1)) {
        tmp = MathFuncs::MathFuncs<fptype>::ldexp(1.0,
                                                  minExp);
      } else {
        tmp = 0.0;
      }
    }
    lineDir.set(i, tmp);
  }
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineDir);
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> cylRandLine(rngAlg &rng,
                                        int minExp,
                                        int maxExp) {
  constexpr const fptype minPos = 0.375, maxPos = 0.625;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  std::uniform_real_distribution<fptype> genDir(-1.0, 1.0);
  /* First build the line */
  Geometry::Vector<dim, fptype> lineDir;
  Geometry::Vector<dim, fptype> lineInt;
  union {
    fptype tmp;
    GenericFP::fpconvert<fptype> bitmanipulate;
  };
  tmp = genPos(rng);
  bitmanipulate.mantissa &= ~((1 << 12) - 1);
  lineInt.set(1, tmp);
  for(int i = 0; i < dim; i++) {
    lineInt.set(i, lineInt.get(1));
    union {
      fptype tmp;
      GenericFP::fpconvert<fptype> bitmanipulate;
    };
    tmp = genDir(rng);
    bitmanipulate.mantissa &= ~((1 << 12) - 1);
    lineDir.set(i, tmp);
  }
  tmp = genPos(rng);
  bitmanipulate.mantissa &= ~((1 << 12) - 1);
  lineInt.set(0, tmp);
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineInt);
}

int main(int argc, char **argv) {
  using fptype = float;
  constexpr const int dim = 3;
  lockCPU();
  std::list<Geometry::Quadric<dim, fptype>> quads;
  const char *outFName = "results";
  int numTests = 1e4;
  int minExp, maxExp;
  if(argc > 1) {
    quads = parseQuadrics<dim, fptype>(argv[1], &minExp,
                                       &maxExp);
  } else {
    quads = parseQuadrics<dim, fptype>("cylinders.csg",
                                       &minExp, &maxExp);
  }
  if(argc > 2) {
    outFName = argv[2];
  }
  if(argc > 3) {
    numTests = atoi(argv[3]);
  }
  randLineGen<dim, fptype> rlg = defRandLine<dim, fptype>;
  if(argc > 4) {
    int lineGenAlg = atoi(argv[4]);
    switch(lineGenAlg) {
      case 1:
        rlg = nestedEllRandLine<dim, fptype>;
        std::cout
            << "Using the nested spheres random lines\n";
        break;
      case 2:
        std::cout << "Using the cylinders random lines\n";
        rlg = cylRandLine<dim, fptype>;
        break;
      default:
        std::cout << "Using the default random lines\n";
        rlg = defRandLine<dim, fptype>;
    }
  }
  bool fixedSeed = false;
  if(argc > 5) {
    if(strcmp(argv[5], "fixed") == 0) {
      fixedSeed = true;
    }
  }
  std::ofstream results(outFName);
  signal(SIGINT, sigInt);
  intersectionTest(quads, results, numTests, rlg, minExp,
                   maxExp, fixedSeed);
  return 0;
}
<commit_msg>Fix typo in the default random line generation<commit_after>
#include "accurate_intersections_approx.hpp"
#include "accurate_intersections_incprec.hpp"
#include "accurate_intersections_resultant.hpp"
#include "geometry.hpp"
#include "line.hpp"
#include "quadric.hpp"
#include "quadric_classify.hpp"
#include "timer.hpp"

#include <array>
#include <fstream>
#include <iomanip>
#include <list>
#include <random>

#include <signal.h>
#include <unistd.h>

#include "tester.hpp"

struct GlobalVars {
  bool run = true;
} globals;

void sigInt(int signum) { globals.run = false; }

template <int dim, typename fptype>
std::list<Geometry::Quadric<dim, fptype>> parseQuadrics(
    const char *fname, int *minExp, int *maxExp) {
  std::ifstream file(fname);
  if(!file.is_open()) {
    return std::list<Geometry::Quadric<dim, fptype>>();
  }
  int buf = 0;
  file >> buf;
  if(minExp != NULL) {
    *minExp = buf;
  }
  file >> buf;
  if(maxExp != NULL) {
    *maxExp = buf;
  }
  if(*minExp > 0) {
    std::cout
        << "Cannot generate a line with these exponents\n"
        << *minExp << ", " << *maxExp << "\n";
    exit(1);
  }
  std::cout << "Using " << *minExp << ", " << *maxExp
            << " as the range of exponents\n";

  using Qf = Geometry::Quadric<dim, fptype>;
  int qtypeCount[QuadricClassify::QUADT_ERRORINVALID];
  for(int i = 0; i < QuadricClassify::QUADT_ERRORINVALID;
      i++)
    qtypeCount[i] = 0;
  std::list<Qf> quads;
  int imQuads = 0;
  int numQuads = 0;
  while(!file.eof()) {
    Qf q;
    file >> q;
    QuadricClassify::QuadType type =
        QuadricClassify::classifyQuadric(q);
    if(!QuadricClassify::isImaginary(type) &&
       type != QuadricClassify::QUADT_ERROR &&
       type != QuadricClassify::QUADT_DEGENERATE &&
       type != QuadricClassify::QUADT_ERRORINVALID) {
      quads.push_back(q);
      qtypeCount[type]++;
    } else {
      std::cout << "Quadric " << numQuads
                << " is invalid, returned type "
                << QuadricClassify::QuadTypeNames[type]
                << "\n";
      imQuads++;
    }
    numQuads++;
  }
  for(int i = 0; i < QuadricClassify::QUADT_ERRORINVALID;
      i++) {
    std::cout << qtypeCount[i] << " "
              << QuadricClassify::QuadTypeNames[i] << "\n";
  }
  return quads;
}

using rngAlg = std::mt19937_64;

template <int dim, typename fptype>
using randLineGen = Geometry::Line<dim, fptype> (*)(
    rngAlg &rng, int minExp, int maxExp);

template <int dim, typename fptype>
void intersectionTest(
    std::list<Geometry::Quadric<dim, fptype>> &quads,
    std::ostream &output, const int numTests,
    randLineGen<dim, fptype> rlgf, int minExp, int maxExp,
    bool fixedSeed) {
  /* First build a scene of quadrics.
   * Then generate random lines on a disk centered at the
   * intersection of the cylinders.
   * Then sort the intersections
   * Finally validate them with a higher precision sort
   */
  using Vf = Geometry::Vector<dim, fptype>;
  using Pf = Geometry::Point<dim, fptype>;
  using Lf = Geometry::Line<dim, fptype>;

  std::random_device rd;
  rngAlg engine(rd());
  if(fixedSeed) {
    engine.seed(682185716);
  }

  const double eps = 1.52587890625e-5;

  Tester<dim, fptype,
         Geometry::IntersectionResultant<dim, fptype>>
      resultantTest(numTests, &quads, eps);

  Tester<dim, fptype, Geometry::IntersectionApproximate<
                          dim, fptype, float>>
      singleTest(numTests, &quads, eps);

  Tester<dim, fptype, Geometry::IntersectionApproximate<
                          dim, fptype, float>>
      doubleTest(numTests, &quads, eps);

  Tester<dim, fptype,
         Geometry::IntersectionIncreasedPrec<dim, fptype>>
      mpTest(numTests, &quads, eps);

  std::vector<Lf> lines;
  /* Run the tests */
  int t;
  for(t = 0; t < numTests && globals.run; t++) {
    Lf line = rlgf(engine, minExp, maxExp);
    /* Then sort the intersections */
    resultantTest.runTest(line);
    singleTest.runTest(line);
    doubleTest.runTest(line);
    mpTest.runTest(line);
    lines.push_back(line);
    singleTest.updateResults(resultantTest.getResults());
    doubleTest.updateResults(resultantTest.getResults());
    mpTest.updateResults(resultantTest.getResults());
    resultantTest.updateResults(resultantTest.getResults());
  }
  /* Output the aggregate of the results */
  output << "Singles Incorrect: "
         << singleTest.getTotalIncorrect() << "\n"
         << "Single Total Time (ns): "
         << singleTest.getTotalTime_ns() << "\n\n";
  output << "Doubles Incorrect: "
         << doubleTest.getTotalIncorrect() << "\n"
         << "Double Total Time (ns): "
         << doubleTest.getTotalTime_ns() << "\n\n";
  output << "Increased Precision Incorrect: "
         << mpTest.getTotalIncorrect() << "\n"
         << "Increased Precision Total Time (ns): "
         << mpTest.getTotalTime_ns() << "\n\n";
  output << "Resultant Total Time (ns): "
         << resultantTest.getTotalTime_ns() << "\n\n\n";
  /* Output all of the results */
  output << "Test #, Singles, Single Times (ns), Single "
            "Correct, Doubles, Double Times (ns), Double "
            "Correct, Increased Precs, MP Time (ns), MP "
            "Correct, Resultants, Resultant Time (ns), "
            "Line Dir X, Line Dir Y, Line Dir Z, "
            "Line Int X, Line Int Y, Line Int Z\n";
  for(int i = 0; i < t; i++) {
    output << i + 1 << ", ";
    printResult(singleTest.getResult(i), output);
    output << ", ";
    printResult(doubleTest.getResult(i), output);
    output << ", ";
    printResult(mpTest.getResult(i), output);
    output << ", ";
    printResult(resultantTest.getResult(i), output);
    output << ", ";
    output << lines[i].getDirection().get(0);
    output << ", ";
    output << lines[i].getDirection().get(1);
    output << ", ";
    output << lines[i].getDirection().get(2);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(0);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(1);
    output << ", ";
    output << lines[i].getIntercept().getOffset().get(2);
    output << "\n";
  }
}

void lockCPU() {
  const int numCPUs = sysconf(_SC_NPROCESSORS_ONLN);
  const int cpuSets =
      numCPUs / CPU_SETSIZE + ((numCPUs % CPU_SETSIZE) > 0);
  cpu_set_t *cpus = new cpu_set_t[cpuSets];
  const size_t cpuSize = sizeof(cpu_set_t[cpuSets]);
  sched_getaffinity(0, cpuSize, cpus);
  for(int i = 1; i < numCPUs; i++) CPU_CLR(i, cpus);
  CPU_SET(0, cpus);
  sched_setaffinity(0, cpuSize, cpus);
  delete[] cpus;
}

template <typename fptype>
bool checkExp(fptype fpVal, int minExp, int maxExp) {
  if(fpVal == fptype(0.0)) {
    return true;
  }
  GenericFP::fpconvert<fptype> *fpbits =
      reinterpret_cast<GenericFP::fpconvert<fptype> *>(
          &fpVal);
  int exponent = fpbits->exponent;
  exponent -= fpbits->centralExp;
  if(exponent < minExp || exponent > maxExp) {
    return false;
  } else {
    return true;
  }
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> defRandLine(rngAlg &rng,
                                        int minExp,
                                        int maxExp) {
  constexpr const fptype minPos = 0, maxPos = 1;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  std::uniform_real_distribution<fptype> genDir(-1.0, 1.0);
  /* First build the line */
  Geometry::Vector<dim, fptype> lineDir;
  Geometry::Vector<dim, fptype> lineInt;
  for(int i = 0; i < dim; i++) {
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genPos(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineInt.set(i, tmp);
    } while(checkExp(lineInt.get(i), minExp, maxExp) ==
            false);
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genDir(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineDir.set(i, tmp);
    } while(checkExp(lineDir.get(i), minExp, maxExp) ==
            false);
  }
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineDir);
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> nestedEllRandLine(rngAlg &rng,
                                              int minExp,
                                              int maxExp) {
  constexpr const fptype minPos = 0.0, maxPos = 1.0;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  Geometry::Vector<dim, fptype> lineInt;
  constexpr const fptype maxDeltaMag = 0.0078125;
  std::uniform_real_distribution<fptype> genDelta(
      -maxDeltaMag, maxDeltaMag);
  Geometry::Vector<dim, fptype> delta;
  for(int i = 0; i < dim; i++) {
    do {
      union {
        fptype tmp;
        GenericFP::fpconvert<fptype> bitmanipulate;
      };
      tmp = genPos(rng);
      bitmanipulate.mantissa &= ~((1 << 12) - 1);
      lineInt.set(i, tmp);
    } while(checkExp(lineInt.get(i), minExp, maxExp) ==
            false);
    delta.set(i, genDelta(rng));
  }
  /* Direct the line towards (1.0, 0.5, 0.5) + delta */
  const Geometry::Vector<dim, fptype> destination =
      Geometry::Vector<dim, fptype>({1.0, 0.5, 0.5}) +
      delta;
  Geometry::Vector<dim, fptype> lineDir =
      destination - lineInt;
  /* Fix the exponent and the mantissa to fit within our
   * bounds for correctness
   */
  int maximum = std::numeric_limits<int>::min();
  for(int i = 0; i < dim; i++) {
    int exp = 0;
    MathFuncs::MathFuncs<fptype>::frexp(lineDir.get(i),
                                        &exp);
    if(exp > maximum) {
      maximum = exp;
    }
  }
  fptype multiplier = MathFuncs::MathFuncs<fptype>::ldexp(
      1.0, maxExp - maximum);
  for(int i = 0; i < dim; i++) {
    union {
      fptype tmp;
      GenericFP::fpconvert<fptype> bitmanipulate;
    };

    tmp = lineDir.get(i) * multiplier;
    bitmanipulate.mantissa &= ~((1 << 12) - 1);
    if(MathFuncs::MathFuncs<fptype>::fabs(tmp) <
       MathFuncs::MathFuncs<fptype>::ldexp(1.0, minExp)) {
      if(MathFuncs::MathFuncs<fptype>::fabs(tmp) >
         MathFuncs::MathFuncs<fptype>::ldexp(1.0,
                                             minExp - 1)) {
        tmp = MathFuncs::MathFuncs<fptype>::ldexp(1.0,
                                                  minExp);
      } else {
        tmp = 0.0;
      }
    }
    lineDir.set(i, tmp);
  }
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineDir);
}

template <int dim, typename fptype>
Geometry::Line<dim, fptype> cylRandLine(rngAlg &rng,
                                        int minExp,
                                        int maxExp) {
  constexpr const fptype minPos = 0.375, maxPos = 0.625;
  std::uniform_real_distribution<fptype> genPos(minPos,
                                                maxPos);
  std::uniform_real_distribution<fptype> genDir(-1.0, 1.0);
  /* First build the line */
  Geometry::Vector<dim, fptype> lineDir;
  Geometry::Vector<dim, fptype> lineInt;
  union {
    fptype tmp;
    GenericFP::fpconvert<fptype> bitmanipulate;
  };
  tmp = genPos(rng);
  bitmanipulate.mantissa &= ~((1 << 12) - 1);
  lineInt.set(1, tmp);
  for(int i = 0; i < dim; i++) {
    lineInt.set(i, lineInt.get(1));
    union {
      fptype tmp;
      GenericFP::fpconvert<fptype> bitmanipulate;
    };
    tmp = genDir(rng);
    bitmanipulate.mantissa &= ~((1 << 12) - 1);
    lineDir.set(i, tmp);
  }
  tmp = genPos(rng);
  bitmanipulate.mantissa &= ~((1 << 12) - 1);
  lineInt.set(0, tmp);
  return Geometry::Line<dim, fptype>(
      Geometry::Point<dim, fptype>(lineInt), lineInt);
}

int main(int argc, char **argv) {
  using fptype = float;
  constexpr const int dim = 3;
  lockCPU();
  std::list<Geometry::Quadric<dim, fptype>> quads;
  const char *outFName = "results";
  int numTests = 1e4;
  int minExp, maxExp;
  if(argc > 1) {
    quads = parseQuadrics<dim, fptype>(argv[1], &minExp,
                                       &maxExp);
  } else {
    quads = parseQuadrics<dim, fptype>("cylinders.csg",
                                       &minExp, &maxExp);
  }
  if(argc > 2) {
    outFName = argv[2];
  }
  if(argc > 3) {
    numTests = atoi(argv[3]);
  }
  randLineGen<dim, fptype> rlg = defRandLine<dim, fptype>;
  if(argc > 4) {
    int lineGenAlg = atoi(argv[4]);
    switch(lineGenAlg) {
      case 1:
        rlg = nestedEllRandLine<dim, fptype>;
        std::cout
            << "Using the nested spheres random lines\n";
        break;
      case 2:
        std::cout << "Using the cylinders random lines\n";
        rlg = cylRandLine<dim, fptype>;
        break;
      default:
        std::cout << "Using the default random lines\n";
        rlg = defRandLine<dim, fptype>;
    }
  }
  bool fixedSeed = false;
  if(argc > 5) {
    if(strcmp(argv[5], "fixed") == 0) {
      fixedSeed = true;
    }
  }
  std::ofstream results(outFName);
  signal(SIGINT, sigInt);
  intersectionTest(quads, results, numTests, rlg, minExp,
                   maxExp, fixedSeed);
  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 Toggl Desktop developers.

#include "./timeentrycellwidget.h"
#include "./ui_timeentrycellwidget.h"

#include "./toggl.h"

TimeEntryCellWidget::TimeEntryCellWidget() : QWidget(0),
ui(new Ui::TimeEntryCellWidget),
guid("") {
    ui->setupUi(this);
}

void TimeEntryCellWidget::display(TimeEntryView *view) {
    guid = view->GUID;
    QString description = (view->Description.length()>0) ? view->Description : "(no description)";
    ui->description->setText(description);
    ui->project->setText(view->ProjectAndTaskLabel);
    ui->project->setStyleSheet("color: '" + getProjectColor(view->Color) + "'");
    ui->duration->setText(view->Duration);

    ui->billable->setVisible(view->Billable);
    ui->tags->setVisible(!view->Tags.isEmpty());

    ui->headerFrame->setVisible(view->IsHeader);
    ui->date->setText(view->DateHeader);
    ui->dateDuration->setText(view->DateDuration);

    ui->tags->setToolTip(
        QString("
"+
                (view->Tags).replace(QString("\t"), QString(", "))+"
"));
    if(view->Description.length()>0) {
        ui->description->setToolTip(
            QString("
"+view->Description+"
"));
    }
    if(view->ProjectAndTaskLabel.length()>0) {
        ui->project->setToolTip(
            QString("
"+view->ProjectAndTaskLabel+"
"));
    }
}

void TimeEntryCellWidget::labelClicked(QString field_name) {
    TogglApi::instance->editTimeEntry(guid, field_name);
}

TimeEntryCellWidget::~TimeEntryCellWidget() {
    delete ui;
}

QSize TimeEntryCellWidget::getSizeHint(bool is_header) {
    if (is_header) {
        return QSize(minimumWidth(), sizeHint().height());
    }
    return QSize(minimumWidth(), ui->dataFrame->height());
}

void TimeEntryCellWidget::mousePressEvent(QMouseEvent *event) {
    TogglApi::instance->editTimeEntry(guid, "");
    QWidget::mousePressEvent(event);
}

void TimeEntryCellWidget::on_continueButton_clicked() {
    TogglApi::instance->continueTimeEntry(guid);
}

QString TimeEntryCellWidget::getProjectColor(QString color) {
    if (color.length() == 0) {
        return QString("#9d9d9d");
    }
    return color;
}
<commit_msg>Added Start Stop time tooltip to duration label (linux) ref: #1249<commit_after>// Copyright 2014 Toggl Desktop developers.

#include "./timeentrycellwidget.h"
#include "./ui_timeentrycellwidget.h"

#include "./toggl.h"

TimeEntryCellWidget::TimeEntryCellWidget() : QWidget(0),
ui(new Ui::TimeEntryCellWidget),
guid("") {
    ui->setupUi(this);
}

void TimeEntryCellWidget::display(TimeEntryView *view) {
    guid = view->GUID;
    QString description = (view->Description.length()>0) ? view->Description : "(no description)";
    ui->description->setText(description);
    ui->project->setText(view->ProjectAndTaskLabel);
    ui->project->setStyleSheet("color: '" + getProjectColor(view->Color) + "'");
    ui->duration->setText(view->Duration);

    ui->billable->setVisible(view->Billable);
    ui->tags->setVisible(!view->Tags.isEmpty());

    ui->headerFrame->setVisible(view->IsHeader);
    ui->date->setText(view->DateHeader);
    ui->dateDuration->setText(view->DateDuration);

    ui->duration->setToolTip(QString("
"+view->StartTimeString+" - "+view->EndTimeString + "
"));

    ui->tags->setToolTip(
        QString("
"+
                (view->Tags).replace(QString("\t"), QString(", "))+"
"));
    if(view->Description.length()>0) {
        ui->description->setToolTip(
            QString("
"+view->Description+"
"));
    }
    if(view->ProjectAndTaskLabel.length()>0) {
        ui->project->setToolTip(
            QString("
"+view->ProjectAndTaskLabel+"
"));
    }
}

void TimeEntryCellWidget::labelClicked(QString field_name) {
    TogglApi::instance->editTimeEntry(guid, field_name);
}

TimeEntryCellWidget::~TimeEntryCellWidget() {
    delete ui;
}

QSize TimeEntryCellWidget::getSizeHint(bool is_header) {
    if (is_header) {
        return QSize(minimumWidth(), sizeHint().height());
    }
    return QSize(minimumWidth(), ui->dataFrame->height());
}

void TimeEntryCellWidget::mousePressEvent(QMouseEvent *event) {
    TogglApi::instance->editTimeEntry(guid, "");
    QWidget::mousePressEvent(event);
}

void TimeEntryCellWidget::on_continueButton_clicked() {
    TogglApi::instance->continueTimeEntry(guid);
}

QString TimeEntryCellWidget::getProjectColor(QString color) {
    if (color.length() == 0) {
        return QString("#9d9d9d");
    }
    return color;
}
<|endoftext|>


<commit_before>//Chapter 6: Simple Functions

#include <iostream>

using namespace std;

int boxCarVolume(int h, int w, int l){
  return h*w*l;
}

double boxCarVolume(double h, double w, double l){
	return h*w*l;
}

void displayBoxCarVolume(int h, int w, int l){
	cout << "The volume of the box car is " << h*w*l << endl;
}

void displayBoxCarVolume(double h, double w, double l){
	cout << "The volume of the box car is " << h*w*l << endl;
}

int main(){
	int height, width, length,stretch = 10;
	cout << "Please enter the height, width and length of the box car\n";
	cin >> height >> width >> length;
	displayBoxCarVolume(height,width,length);
	cout << "The volume of an elongated box car is "
		 << boxCarVolume(height, width, length + stretch)
		 << endl;
	cout << "Please enter the floating point value for the height, width and length of the box car\n";
	double doubleHeight, doubleWidth, doubleLength;
	cin >> doubleHeight >> doubleWidth >> doubleLength;
	displayBoxCarVolume(doubleHeight, doubleWidth, doubleLength);
	cout << "The volume of an elongated box car is "
		 << boxCarVolume(doubleHeight, doubleWidth, doubleLength + (double)stretch)
		 << endl;
	return 0;
}
<commit_msg>Delete Chapter_Six.cpp<commit_after><|endoftext|>


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

#include "base/command_line.h"
#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_window.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs = 500;

const wchar_t kSimplePage[] = L"files/devtools/simple_page.html";

class DevToolsSanityTest : public InProcessBrowserTest {
 public:
  DevToolsSanityTest() {
    set_show_window(true);
    EnableDOMAutomation();
  }

  void OpenWebInspector(const std::wstring& page_url) {
    HTTPTestServer* server = StartHTTPServer();
    GURL url = server->TestServerPageW(page_url);
    ui_test_utils::NavigateToURL(browser(), url);

    TabContents* tab = browser()->GetSelectedTabContents();
    RenderViewHost* inspected_rvh = tab->render_view_host();
    DevToolsManager* devtools_manager = g_browser_process->devtools_manager();
    devtools_manager->OpenDevToolsWindow(inspected_rvh);

    DevToolsClientHost* client_host =
        devtools_manager->GetDevToolsClientHostFor(inspected_rvh);
    DevToolsWindow* window = client_host->AsDevToolsWindow();
    RenderViewHost* client_rvh = window->GetRenderViewHost();
    client_contents_ = client_rvh->delegate()->GetAsTabContents();
    ui_test_utils::WaitForNavigation(&client_contents_->controller());
  }

  void AssertTrue(const std::string& expr) {
    AssertEquals("true", expr);
  }

  void AssertEquals(const std::string& expected, const std::string& expr) {
    std::string call = StringPrintf(
        "try {"
        "  var domAgent = devtools.tools.getDomAgent();"
        "  var netAgent = devtools.tools.getNetAgent();"
        "  var doc = domAgent.getDocument();"
        "  window.domAutomationController.send((%s) + '');"
        "} catch(e) {"
        "  window.domAutomationController.send(e.toString());"
        "}", expr.c_str());
    std::string result;
    ASSERT_TRUE(
        ui_test_utils::ExecuteJavaScriptAndExtractString(
            client_contents_,
            L"",
            UTF8ToWide(call),
            &result));
    ASSERT_EQ(expected, result);
  }

 protected:
  TabContents* client_contents_;
};

// WebInspector opens.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, OpenWebInspector) {
  OpenWebInspector(kSimplePage);
  AssertTrue("typeof DevToolsHost == 'object' && !DevToolsHost.isStub");
  AssertTrue("!!doc.documentElement");
}

// Tests elements panel basics.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, ElementsPanel) {
  OpenWebInspector(kSimplePage);
  AssertEquals("HTML", "doc.documentElement.nodeName");
  AssertTrue("doc.documentElement.hasChildNodes()");
}

// Tests resources panel basics.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, ResourcesPanel) {
  OpenWebInspector(kSimplePage);
  std::string func =
      "function() {"
      "  var tokens = [];"
      "  var resources = netAgent.resources_;"
      "  for (var id in resources) {"
      "    tokens.push(resources[id].lastPathComponent);"
      "  }"
      "  return tokens.join(',');"
      "}()";
  AssertEquals("simple_page.html", func);
}

}  // namespace
<commit_msg>Disable dev tools sanity tests to see if it helps interactive ui tests to recover.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/automation/ui_controls.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_window.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs = 500;

const wchar_t kSimplePage[] = L"files/devtools/simple_page.html";

class DevToolsSanityTest : public InProcessBrowserTest {
 public:
  DevToolsSanityTest() {
    set_show_window(true);
    EnableDOMAutomation();
  }

  void OpenWebInspector(const std::wstring& page_url) {
    HTTPTestServer* server = StartHTTPServer();
    GURL url = server->TestServerPageW(page_url);
    ui_test_utils::NavigateToURL(browser(), url);

    TabContents* tab = browser()->GetSelectedTabContents();
    RenderViewHost* inspected_rvh = tab->render_view_host();
    DevToolsManager* devtools_manager = g_browser_process->devtools_manager();
    devtools_manager->OpenDevToolsWindow(inspected_rvh);

    DevToolsClientHost* client_host =
        devtools_manager->GetDevToolsClientHostFor(inspected_rvh);
    DevToolsWindow* window = client_host->AsDevToolsWindow();
    RenderViewHost* client_rvh = window->GetRenderViewHost();
    client_contents_ = client_rvh->delegate()->GetAsTabContents();
    ui_test_utils::WaitForNavigation(&client_contents_->controller());
  }

  void AssertTrue(const std::string& expr) {
    AssertEquals("true", expr);
  }

  void AssertEquals(const std::string& expected, const std::string& expr) {
    std::string call = StringPrintf(
        "try {"
        "  var domAgent = devtools.tools.getDomAgent();"
        "  var netAgent = devtools.tools.getNetAgent();"
        "  var doc = domAgent.getDocument();"
        "  window.domAutomationController.send((%s) + '');"
        "} catch(e) {"
        "  window.domAutomationController.send(e.toString());"
        "}", expr.c_str());
    std::string result;
    ASSERT_TRUE(
        ui_test_utils::ExecuteJavaScriptAndExtractString(
            client_contents_,
            L"",
            UTF8ToWide(call),
            &result));
    ASSERT_EQ(expected, result);
  }

 protected:
  TabContents* client_contents_;
};

// WebInspector opens.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_OpenWebInspector) {
  OpenWebInspector(kSimplePage);
  AssertTrue("typeof DevToolsHost == 'object' && !DevToolsHost.isStub");
  AssertTrue("!!doc.documentElement");
}

// Tests elements panel basics.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_ElementsPanel) {
  OpenWebInspector(kSimplePage);
  AssertEquals("HTML", "doc.documentElement.nodeName");
  AssertTrue("doc.documentElement.hasChildNodes()");
}

// Tests resources panel basics.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_ResourcesPanel) {
  OpenWebInspector(kSimplePage);
  std::string func =
      "function() {"
      "  var tokens = [];"
      "  var resources = netAgent.resources_;"
      "  for (var id in resources) {"
      "    tokens.push(resources[id].lastPathComponent);"
      "  }"
      "  return tokens.join(',');"
      "}()";
  AssertEquals("simple_page.html", func);
}

}  // namespace
<|endoftext|>


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

#include "chrome/browser/extensions/extension_apitest.h"

// Flaky, http://crbug.com/20828. Please consult phajdan.jr before re-enabling.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Tabs) {
  ASSERT_TRUE(RunExtensionTest("tabs")) << message_;
}
<commit_msg>Re-disable ExtensionApiTest.Tabs (flakey)<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

// Flaky, http://crbug.com/20828. Please consult phajdan.jr before re-enabling.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_Tabs) {
  ASSERT_TRUE(RunExtensionTest("tabs")) << message_;
}
<|endoftext|>


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

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"

// Tabs is flaky on chromeos and linux views debug build.
// http://crbug.com/48920
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_Tabs FLAKY_Tabs
#else
#define MAYBE_Tabs Tabs
#endif

// TabOnRemoved is flaky on chromeos and linux views debug build.
// http://crbug.com/49258
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_TabOnRemoved FLAKY_TabOnRemoved
#else
#define MAYBE_TabOnRemoved TabOnRemoved
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs) {
  ASSERT_TRUE(StartHTTPServer());

  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionTest("tabs/basics")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabGetCurrent) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabConnect) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOnRemoved) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CaptureVisibleTab) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/capture_visible_tab")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(StartHTTPServer());

  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}
<commit_msg>Mark CaptureVisibleTab as flaky.  This is failing on kermic 64 machine, which only exists in tryservers.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"

// Tabs is flaky on chromeos and linux views debug build.
// http://crbug.com/48920
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_Tabs FLAKY_Tabs
#else
#define MAYBE_Tabs Tabs
#endif

// TabOnRemoved is flaky on chromeos and linux views debug build.
// http://crbug.com/49258
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_TabOnRemoved FLAKY_TabOnRemoved
#else
#define MAYBE_TabOnRemoved TabOnRemoved
#endif

// CaptureVisibleTab fails on karmic 64 bit.
// http://crbug.com/49040
#if defined(OS_LINUX) && defined(__x86_64__) && !defined(NDEBUG)
#define MAYBE_CaptureVisibleTab FLAKY_CaptureVisibleTab
#else
#define MAYBE_CaptureVisibleTab CaptureVisibleTab
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs) {
  ASSERT_TRUE(StartHTTPServer());

  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionTest("tabs/basics")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabGetCurrent) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabConnect) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOnRemoved) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_CaptureVisibleTab) {
  ASSERT_TRUE(StartHTTPServer());
  ASSERT_TRUE(RunExtensionTest("tabs/capture_visible_tab")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(StartHTTPServer());

  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}
<|endoftext|>


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

#include <stdint.h>

#include <iostream>
#include <vector>

#include <x86intrin.h>

#include "util/benchmark.h"
#include "util/cpu-info.h"
#include "util/sse-util.h"

using namespace std;
using namespace impala;

// Test hash functions that take integers as arguments and produce integers as the result.
//
// Machine Info: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
// 32 -> 32:             Function     Rate (iters/ms)          Comparison
// ----------------------------------------------------------------------
//                       Jenkins2               14.06                  1X
//                       Jenkins1               16.97              1.207X
//                        MultRot               19.14              1.361X
//               MultiplyAddShift               21.21              1.509X
//                  MultiplyShift                25.3              1.799X
//                            CRC               25.53              1.816X

// Make a random uint32_t, avoiding the absent high bit and the low-entropy low bits
// produced by rand().
uint32_t MakeRandU32() {
  uint32_t result = (rand() >> 8) & 0xffff;
  result <<= 16;
  result |= (rand() >> 8) & 0xffff;
  return result;
}

// Almost universal hashing, M. Dietzfelbinger, T. Hagerup, J. Katajainen, and M.
// Penttonen, "A reliable randomized algorithm for the closest-pair problem".
uint32_t MultiplyShift(uint32_t x) {
  static const uint32_t m = 0x61eaf8e9u;
  return x*m;
}

// 2-independent hashing. M. Dietzfelbinger, "Universal hashing and k-wise independent
// random variables via integer arithmetic without primes"
uint32_t MultiplyAddShift(uint32_t x) {
  static const uint64_t m = 0xa1f1bd3e020b4be0ull, a = 0x86b0426193d86e66ull;
  return (static_cast<uint64_t>(x) * m + a) >> 32;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
int32_t Jenkins1(int32_t x) {
  x = ~x + (x << 15);  // x = (x << 15) - x - 1;
  x = x ^ _rotr(x, 12);
  x = x + (x << 2);
  x = x ^ _rotr(x, 4);
  x = x * 2057;  // x = (x + (x << 3)) + (x << 11);
  x = x ^ _rotr(x, 16);
  return x;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
uint32_t Jenkins2(uint32_t a) {
  a = (a + 0x7ed55d16) + (a << 12);
  a = (a ^ 0xc761c23c) ^ (a >> 19);
  a = (a + 0x165667b1) + (a << 5);
  a = (a + 0xd3a2646c) ^ (a << 9);
  a = (a + 0xfd7046c5) + (a << 3);
  a = (a ^ 0xb55a4f09) ^ (a >> 16);
  return a;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
int32_t MultRot(int32_t key) {
  static const int32_t c2 = 0x27d4eb2d;  // a prime or an odd constant
  key = (key ^ 61) ^ _rotr(key, 16);
  key = key + (key << 3);
  key = key ^ _rotr(key, 4);
  key = key * c2;
  key = key ^ _rotr(key, 15);
  return key;
}

uint32_t CRC(uint32_t x) {
  return SSE4_crc32_u32(x,0xab8ce2abu);
}

template<typename T, T (*HASH)(T)>
void Run(int batch_size, void* data) {
  vector<T>* d = reinterpret_cast<vector<T>*>(data);
  for (int i = 0; i < batch_size; ++i) {
    for (int j = 0; j < d->size(); ++j) {
      (*d)[j] = HASH((*d)[j]);
    }
  }
}

int main() {
  CpuInfo::Init();
  cout << endl
       << Benchmark::GetMachineInfo() << endl;

  vector<uint32_t> ud(1 << 15);
  for (size_t i = 0; i < ud.size(); ++i) {
    ud[i] = MakeRandU32();
  }

  Benchmark suite("32 -> 32");

#define BENCH(T,x) suite.AddBenchmark(#x, Run<T, x>, &ud)
  BENCH(uint32_t, Jenkins2);
  BENCH(int32_t, Jenkins1);
  BENCH(int32_t, MultRot);
  BENCH(uint32_t, MultiplyAddShift);
  BENCH(uint32_t, MultiplyShift);
  BENCH(uint32_t, CRC);
#undef BENCH

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

#include <stdint.h>

#include <iostream>
#include <limits>
#include <vector>

#include "util/benchmark.h"
#include "util/cpu-info.h"
#include "util/sse-util.h"

using namespace std;
using namespace impala;

// Test hash functions that take integers as arguments and produce integers as the result.
//
// Machine Info: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
// 32 -> 32:             Function     Rate (iters/ms)          Comparison
// ----------------------------------------------------------------------
//                       Jenkins2               14.06                  1X
//                       Jenkins1               16.97              1.207X
//                        MultRot               19.14              1.361X
//               MultiplyAddShift               21.21              1.509X
//                  MultiplyShift                25.3              1.799X
//                            CRC               25.53              1.816X

// Rotate 32 bits right by 'shift'. This is _rotr in the intel instrinsics, but that isn't
// usable on Clang yet. Fortunately, both GCC and Clang can optimize this to use the 'ror'
// instruction.
uint32_t RotateRight(uint32_t x, int shift) {
  DCHECK_GT(shift, 0);
  DCHECK_LT(shift, std::numeric_limits<decltype(x)>::digits);
  return (x << (std::numeric_limits<decltype(x)>::digits - shift)) | (x >> shift);
}

// Make a random uint32_t, avoiding the absent high bit and the low-entropy low bits
// produced by rand().
uint32_t MakeRandU32() {
  uint32_t result = (rand() >> 8) & 0xffff;
  result <<= 16;
  result |= (rand() >> 8) & 0xffff;
  return result;
}

// Almost universal hashing, M. Dietzfelbinger, T. Hagerup, J. Katajainen, and M.
// Penttonen, "A reliable randomized algorithm for the closest-pair problem".
uint32_t MultiplyShift(uint32_t x) {
  static const uint32_t m = 0x61eaf8e9u;
  return x*m;
}

// 2-independent hashing. M. Dietzfelbinger, "Universal hashing and k-wise independent
// random variables via integer arithmetic without primes"
uint32_t MultiplyAddShift(uint32_t x) {
  static const uint64_t m = 0xa1f1bd3e020b4be0ull, a = 0x86b0426193d86e66ull;
  return (static_cast<uint64_t>(x) * m + a) >> 32;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
int32_t Jenkins1(int32_t x) {
  x = ~x + (x << 15);  // x = (x << 15) - x - 1;
  x = x ^ RotateRight(x, 12);
  x = x + (x << 2);
  x = x ^ RotateRight(x, 4);
  x = x * 2057;  // x = (x + (x << 3)) + (x << 11);
  x = x ^ RotateRight(x, 16);
  return x;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
uint32_t Jenkins2(uint32_t a) {
  a = (a + 0x7ed55d16) + (a << 12);
  a = (a ^ 0xc761c23c) ^ (a >> 19);
  a = (a + 0x165667b1) + (a << 5);
  a = (a + 0xd3a2646c) ^ (a << 9);
  a = (a + 0xfd7046c5) + (a << 3);
  a = (a ^ 0xb55a4f09) ^ (a >> 16);
  return a;
}

// From http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm:
int32_t MultRot(int32_t key) {
  static const int32_t c2 = 0x27d4eb2d;  // a prime or an odd constant
  key = (key ^ 61) ^ RotateRight(key, 16);
  key = key + (key << 3);
  key = key ^ RotateRight(key, 4);
  key = key * c2;
  key = key ^ RotateRight(key, 15);
  return key;
}

uint32_t CRC(uint32_t x) {
  return SSE4_crc32_u32(x,0xab8ce2abu);
}

template<typename T, T (*HASH)(T)>
void Run(int batch_size, void* data) {
  vector<T>* d = reinterpret_cast<vector<T>*>(data);
  for (int i = 0; i < batch_size; ++i) {
    for (int j = 0; j < d->size(); ++j) {
      (*d)[j] = HASH((*d)[j]);
    }
  }
}

int main() {
  CpuInfo::Init();
  cout << endl
       << Benchmark::GetMachineInfo() << endl;

  vector<uint32_t> ud(1 << 15);
  for (size_t i = 0; i < ud.size(); ++i) {
    ud[i] = MakeRandU32();
  }

  Benchmark suite("32 -> 32");

#define BENCH(T,x) suite.AddBenchmark(#x, Run<T, x>, &ud)
  BENCH(uint32_t, Jenkins2);
  BENCH(int32_t, Jenkins1);
  BENCH(int32_t, MultRot);
  BENCH(uint32_t, MultiplyAddShift);
  BENCH(uint32_t, MultiplyShift);
  BENCH(uint32_t, CRC);
#undef BENCH

  cout << suite.Measure() << endl;
}
<|endoftext|>


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

#include <string>

#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/system_monitor/system_monitor.h"
#include "base/values.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_pref_service.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
// This global variable is used to check that value returned to different
// observers is the same.
Profile* g_created_profile;

}  // namespace

class ProfileManagerTest : public TestingBrowserProcessTest {
 protected:
  ProfileManagerTest()
      : ui_thread_(BrowserThread::UI, &message_loop_),
        file_thread_(BrowserThread::FILE, &message_loop_),
        profile_manager_(new ProfileManagerWithoutInit),
        local_state_(testing_browser_process_.get()) {
  }

  virtual void SetUp() {
    // Create a new temporary directory, and store the path
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  virtual void TearDown() {
    profile_manager_.reset();
  }

  class MockObserver : public ProfileManagerObserver {
   public:
    MOCK_METHOD1(OnProfileCreated, void(Profile* profile));
  };

  // The path to temporary directory used to contain the test operations.
  ScopedTempDir temp_dir_;

  MessageLoopForUI message_loop_;
  BrowserThread ui_thread_;
  BrowserThread file_thread_;

  base::SystemMonitor system_monitor_dummy_;

  // Also will test profile deletion.
  scoped_ptr<ProfileManager> profile_manager_;

  ScopedTestingLocalState local_state_;
};

TEST_F(ProfileManagerTest, GetProfile) {
  FilePath dest_path = temp_dir_.path();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  Profile* profile;

  // Successfully create a profile.
  profile = profile_manager_->GetProfile(dest_path);
  EXPECT_TRUE(profile);

  // The profile already exists when we call GetProfile. Just load it.
  EXPECT_EQ(profile, profile_manager_->GetProfile(dest_path));
}

TEST_F(ProfileManagerTest, DefaultProfileDir) {
  CommandLine *cl = CommandLine::ForCurrentProcess();
  std::string profile_dir("my_user");

  cl->AppendSwitch(switches::kTestType);

  FilePath expected_default =
      FilePath().AppendASCII(chrome::kNotSignedInProfile);
  EXPECT_EQ(expected_default.value(),
            profile_manager_->GetCurrentProfileDir().value());
}

#if defined(OS_CHROMEOS)
// This functionality only exists on Chrome OS.
TEST_F(ProfileManagerTest, LoggedInProfileDir) {
  CommandLine *cl = CommandLine::ForCurrentProcess();
  std::string profile_dir("my_user");

  cl->AppendSwitchASCII(switches::kLoginProfile, profile_dir);
  cl->AppendSwitch(switches::kTestType);

  FilePath expected_default =
      FilePath().AppendASCII(chrome::kNotSignedInProfile);
  EXPECT_EQ(expected_default.value(),
            profile_manager_->GetCurrentProfileDir().value());

  profile_manager_->Observe(NotificationType::LOGIN_USER_CHANGED,
                           NotificationService::AllSources(),
                           NotificationService::NoDetails());
  FilePath expected_logged_in(profile_dir);
  EXPECT_EQ(expected_logged_in.value(),
            profile_manager_->GetCurrentProfileDir().value());
  VLOG(1) << temp_dir_.path().Append(
      profile_manager_->GetCurrentProfileDir()).value();
}

#endif

TEST_F(ProfileManagerTest, RegisterProfileName) {
  // Create a test profile.
  FilePath dest_path1 = temp_dir_.path();
  std::string dir_base("New Profile 1");
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
  Profile* profile1;
  profile1 = profile_manager_->GetProfile(dest_path1);
  ASSERT_TRUE(profile1);

  // Simulate registration of the profile name (normally triggered by the
  // change of the kGoogleServicesUsername preference):
  std::string testname("testname");
  profile1->GetPrefs()->SetString(prefs::kGoogleServicesUsername, testname);
  profile_manager_->RegisterProfileName(profile1);

  // Profile name should be associated with the directory in Local State.
  std::string stored_profile_name;
  const DictionaryValue* path_map = static_cast<const DictionaryValue*>(
      local_state_.Get()->GetUserPref(prefs::kProfileDirectoryMap));
  path_map->GetString(dir_base, &stored_profile_name);
  ASSERT_STREQ(testname.c_str(), stored_profile_name.c_str());
}

TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
  FilePath dest_path1 = temp_dir_.path();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));

  FilePath dest_path2 = temp_dir_.path();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  Profile* profile1;
  Profile* profile2;

  // Successfully create the profiles.
  profile1 = profile_manager_->GetProfile(dest_path1);
  ASSERT_TRUE(profile1);

  profile2 = profile_manager_->GetProfile(dest_path2);
  ASSERT_TRUE(profile2);

  // Force lazy-init of some profile services to simulate use.
  EXPECT_TRUE(profile1->GetHistoryService(Profile::EXPLICIT_ACCESS));
  EXPECT_TRUE(profile1->GetBookmarkModel());
  EXPECT_TRUE(profile2->GetBookmarkModel());
  EXPECT_TRUE(profile2->GetHistoryService(Profile::EXPLICIT_ACCESS));

  // Make sure any pending tasks run before we destroy the profiles.
  message_loop_.RunAllPending();

  profile_manager_.reset();

  // Make sure history cleans up correctly.
  message_loop_.RunAllPending();
}

#if !defined(OS_CHROMEOS)  // disable temporary while jam debugs debug failures

// Tests asynchronous profile creation mechanism.
TEST_F(ProfileManagerTest, CreateProfileAsync) {
  FilePath dest_path =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(1);

  profile_manager_->CreateProfileAsync(dest_path, &mock_observer);

  message_loop_.RunAllPending();
}

MATCHER(SameNotNull, "The same non-NULL value for all cals.") {
  if (!g_created_profile)
    g_created_profile = arg;
  return g_created_profile == arg;
}

TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) {
  FilePath dest_path =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));

  g_created_profile = NULL;

  MockObserver mock_observer1;
  EXPECT_CALL(mock_observer1, OnProfileCreated(SameNotNull())).Times(1);
  MockObserver mock_observer2;
  EXPECT_CALL(mock_observer2, OnProfileCreated(SameNotNull())).Times(1);
  MockObserver mock_observer3;
  EXPECT_CALL(mock_observer3, OnProfileCreated(SameNotNull())).Times(1);

  profile_manager_->CreateProfileAsync(dest_path, &mock_observer1);
  profile_manager_->CreateProfileAsync(dest_path, &mock_observer2);
  profile_manager_->CreateProfileAsync(dest_path, &mock_observer3);

  message_loop_.RunAllPending();
}

TEST_F(ProfileManagerTest, CreateProfilesAsync) {
  FilePath dest_path1 =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 1"));
  FilePath dest_path2 =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 2"));

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(2);

  profile_manager_->CreateProfileAsync(dest_path1, &mock_observer);
  profile_manager_->CreateProfileAsync(dest_path2, &mock_observer);

  message_loop_.RunAllPending();
}
#endif

<commit_msg>fix clang error on cros<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/system_monitor/system_monitor.h"
#include "base/values.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_pref_service.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if !defined(OS_CHROMEOS)  // disable temporary while jam debugs debug failures

namespace {
// This global variable is used to check that value returned to different
// observers is the same.
Profile* g_created_profile;

}  // namespace

#endif

class ProfileManagerTest : public TestingBrowserProcessTest {
 protected:
  ProfileManagerTest()
      : ui_thread_(BrowserThread::UI, &message_loop_),
        file_thread_(BrowserThread::FILE, &message_loop_),
        profile_manager_(new ProfileManagerWithoutInit),
        local_state_(testing_browser_process_.get()) {
  }

  virtual void SetUp() {
    // Create a new temporary directory, and store the path
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  virtual void TearDown() {
    profile_manager_.reset();
  }

  class MockObserver : public ProfileManagerObserver {
   public:
    MOCK_METHOD1(OnProfileCreated, void(Profile* profile));
  };

  // The path to temporary directory used to contain the test operations.
  ScopedTempDir temp_dir_;

  MessageLoopForUI message_loop_;
  BrowserThread ui_thread_;
  BrowserThread file_thread_;

  base::SystemMonitor system_monitor_dummy_;

  // Also will test profile deletion.
  scoped_ptr<ProfileManager> profile_manager_;

  ScopedTestingLocalState local_state_;
};

TEST_F(ProfileManagerTest, GetProfile) {
  FilePath dest_path = temp_dir_.path();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  Profile* profile;

  // Successfully create a profile.
  profile = profile_manager_->GetProfile(dest_path);
  EXPECT_TRUE(profile);

  // The profile already exists when we call GetProfile. Just load it.
  EXPECT_EQ(profile, profile_manager_->GetProfile(dest_path));
}

TEST_F(ProfileManagerTest, DefaultProfileDir) {
  CommandLine *cl = CommandLine::ForCurrentProcess();
  std::string profile_dir("my_user");

  cl->AppendSwitch(switches::kTestType);

  FilePath expected_default =
      FilePath().AppendASCII(chrome::kNotSignedInProfile);
  EXPECT_EQ(expected_default.value(),
            profile_manager_->GetCurrentProfileDir().value());
}

#if defined(OS_CHROMEOS)
// This functionality only exists on Chrome OS.
TEST_F(ProfileManagerTest, LoggedInProfileDir) {
  CommandLine *cl = CommandLine::ForCurrentProcess();
  std::string profile_dir("my_user");

  cl->AppendSwitchASCII(switches::kLoginProfile, profile_dir);
  cl->AppendSwitch(switches::kTestType);

  FilePath expected_default =
      FilePath().AppendASCII(chrome::kNotSignedInProfile);
  EXPECT_EQ(expected_default.value(),
            profile_manager_->GetCurrentProfileDir().value());

  profile_manager_->Observe(NotificationType::LOGIN_USER_CHANGED,
                           NotificationService::AllSources(),
                           NotificationService::NoDetails());
  FilePath expected_logged_in(profile_dir);
  EXPECT_EQ(expected_logged_in.value(),
            profile_manager_->GetCurrentProfileDir().value());
  VLOG(1) << temp_dir_.path().Append(
      profile_manager_->GetCurrentProfileDir()).value();
}

#endif

TEST_F(ProfileManagerTest, RegisterProfileName) {
  // Create a test profile.
  FilePath dest_path1 = temp_dir_.path();
  std::string dir_base("New Profile 1");
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
  Profile* profile1;
  profile1 = profile_manager_->GetProfile(dest_path1);
  ASSERT_TRUE(profile1);

  // Simulate registration of the profile name (normally triggered by the
  // change of the kGoogleServicesUsername preference):
  std::string testname("testname");
  profile1->GetPrefs()->SetString(prefs::kGoogleServicesUsername, testname);
  profile_manager_->RegisterProfileName(profile1);

  // Profile name should be associated with the directory in Local State.
  std::string stored_profile_name;
  const DictionaryValue* path_map = static_cast<const DictionaryValue*>(
      local_state_.Get()->GetUserPref(prefs::kProfileDirectoryMap));
  path_map->GetString(dir_base, &stored_profile_name);
  ASSERT_STREQ(testname.c_str(), stored_profile_name.c_str());
}

TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
  FilePath dest_path1 = temp_dir_.path();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));

  FilePath dest_path2 = temp_dir_.path();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  Profile* profile1;
  Profile* profile2;

  // Successfully create the profiles.
  profile1 = profile_manager_->GetProfile(dest_path1);
  ASSERT_TRUE(profile1);

  profile2 = profile_manager_->GetProfile(dest_path2);
  ASSERT_TRUE(profile2);

  // Force lazy-init of some profile services to simulate use.
  EXPECT_TRUE(profile1->GetHistoryService(Profile::EXPLICIT_ACCESS));
  EXPECT_TRUE(profile1->GetBookmarkModel());
  EXPECT_TRUE(profile2->GetBookmarkModel());
  EXPECT_TRUE(profile2->GetHistoryService(Profile::EXPLICIT_ACCESS));

  // Make sure any pending tasks run before we destroy the profiles.
  message_loop_.RunAllPending();

  profile_manager_.reset();

  // Make sure history cleans up correctly.
  message_loop_.RunAllPending();
}

#if !defined(OS_CHROMEOS)  // disable temporary while jam debugs debug failures

// Tests asynchronous profile creation mechanism.
TEST_F(ProfileManagerTest, CreateProfileAsync) {
  FilePath dest_path =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(1);

  profile_manager_->CreateProfileAsync(dest_path, &mock_observer);

  message_loop_.RunAllPending();
}

MATCHER(SameNotNull, "The same non-NULL value for all cals.") {
  if (!g_created_profile)
    g_created_profile = arg;
  return g_created_profile == arg;
}

TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) {
  FilePath dest_path =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile"));

  g_created_profile = NULL;

  MockObserver mock_observer1;
  EXPECT_CALL(mock_observer1, OnProfileCreated(SameNotNull())).Times(1);
  MockObserver mock_observer2;
  EXPECT_CALL(mock_observer2, OnProfileCreated(SameNotNull())).Times(1);
  MockObserver mock_observer3;
  EXPECT_CALL(mock_observer3, OnProfileCreated(SameNotNull())).Times(1);

  profile_manager_->CreateProfileAsync(dest_path, &mock_observer1);
  profile_manager_->CreateProfileAsync(dest_path, &mock_observer2);
  profile_manager_->CreateProfileAsync(dest_path, &mock_observer3);

  message_loop_.RunAllPending();
}

TEST_F(ProfileManagerTest, CreateProfilesAsync) {
  FilePath dest_path1 =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 1"));
  FilePath dest_path2 =
      temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 2"));

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(2);

  profile_manager_->CreateProfileAsync(dest_path1, &mock_observer);
  profile_manager_->CreateProfileAsync(dest_path2, &mock_observer);

  message_loop_.RunAllPending();
}
#endif

<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTranslator>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    weight_unit(Grams),
    lye_type(NaOH),
    ui(new Ui::MainWindow),
    oils("oils.sqlite")
{
    ui->setupUi(this);
    ui->retranslateUi(this);

    sort_oils_by(tr("Hardness"), false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::set_lye_type_naoh()   { lye_type = NaOH;   calculate_lye(); }
void MainWindow::set_lye_type_koh()    { lye_type = KOH;    calculate_lye(); }
void MainWindow::set_lye_type_koh_90() { lye_type = KOH_90; calculate_lye(); }

void MainWindow::set_weight_unit_grams() { weight_unit = Grams; }

void MainWindow::new_weight_grams(double v) {
    if(weight_unit == Grams) {
        emit set_weight_pounds(v/453.592);
        emit set_weight_ounces(v/28.3495);
    }
}

void MainWindow::set_weight_unit_pounds() { weight_unit = Pounds; }

void MainWindow::new_weight_pounds(double v) {
    if(weight_unit == Pounds) {
        emit set_weight_grams(v*453.592);
        emit set_weight_ounces(v*16);
    }
}

void MainWindow::set_weight_unit_ounces() { weight_unit = Ounces; }

void MainWindow::new_weight_ounces(double v) {
    if(weight_unit == Ounces) {
        emit set_weight_grams(v*28.3495);
        emit set_weight_pounds(v/16);
    }
}
void MainWindow::calculate_lye() {

}

void MainWindow::sort_oils_by(const QString &key, bool ascending) {
    QList<Oil> oil_list = oils.get_oils();

    ui->oil_list->clear();

    if(key == tr("Name")) {
        std::sort(oil_list.begin(),
                  oil_list.end(),
                  [ascending](const Oil &a, const Oil &b) { return (a.get_name() < b.get_name()) == ascending; });
    } else {
        Oil::Getter get_key = Oil::get_getter(key);
        std::sort(oil_list.begin(),
                  oil_list.end(),
                  [get_key, ascending](const Oil &a, const Oil &b) {
            return ((a.*get_key)() < (b.*get_key)()) == ascending; });
    }

    for(QList<Oil>::iterator it = oil_list.begin();
        it != oil_list.end();
        it++) {
        ui->oil_list->addItem(it->get_name());
    }

}
<commit_msg>Nicer for each<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTranslator>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    weight_unit(Grams),
    lye_type(NaOH),
    ui(new Ui::MainWindow),
    oils("oils.sqlite")
{
    ui->setupUi(this);
    ui->retranslateUi(this);

    sort_oils_by(tr("Hardness"), false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::set_lye_type_naoh()   { lye_type = NaOH;   calculate_lye(); }
void MainWindow::set_lye_type_koh()    { lye_type = KOH;    calculate_lye(); }
void MainWindow::set_lye_type_koh_90() { lye_type = KOH_90; calculate_lye(); }

void MainWindow::set_weight_unit_grams() { weight_unit = Grams; }

void MainWindow::new_weight_grams(double v) {
    if(weight_unit == Grams) {
        emit set_weight_pounds(v/453.592);
        emit set_weight_ounces(v/28.3495);
    }
}

void MainWindow::set_weight_unit_pounds() { weight_unit = Pounds; }

void MainWindow::new_weight_pounds(double v) {
    if(weight_unit == Pounds) {
        emit set_weight_grams(v*453.592);
        emit set_weight_ounces(v*16);
    }
}

void MainWindow::set_weight_unit_ounces() { weight_unit = Ounces; }

void MainWindow::new_weight_ounces(double v) {
    if(weight_unit == Ounces) {
        emit set_weight_grams(v*28.3495);
        emit set_weight_pounds(v/16);
    }
}
void MainWindow::calculate_lye() {

}

void MainWindow::sort_oils_by(const QString &key, bool ascending) {
    QList<Oil> oil_list = oils.get_oils();

    ui->oil_list->clear();

    if(key == tr("Name")) {
        std::sort(oil_list.begin(),
                  oil_list.end(),
                  [ascending](const Oil &a, const Oil &b) { return (a.get_name() < b.get_name()) == ascending; });
    } else {
        Oil::Getter get_key = Oil::get_getter(key);
        std::sort(oil_list.begin(),
                  oil_list.end(),
                  [get_key, ascending](const Oil &a, const Oil &b) {
            return ((a.*get_key)() < (b.*get_key)()) == ascending; });
    }

    for(auto &oil : oil_list) {
        ui->oil_list->addItem(oil.get_name());
    }
}
<|endoftext|>