<commit_before>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

/*
 * Collection of heap-less containers and functions.
 */

#pragma once

#include <type_traits>
#include <algorithm>
#include <cassert>
#include <cstdarg>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <limits>

namespace os
{
namespace heapless
{
/**
 * Converts any signed or unsigned integer or boolean to string and returns it by value.
 * The argument must be of integral type, otherwise the call will be rejected by SFINAE.
 * Usage examples:
 *      intToString(var)
 *      intToString<16>(var)
 *      intToString<2>(var).c_str()
 * It is safe to obtain a reference to the returned string and pass it to another function as an argument,
 * which enables use cases like this (this example is somewhat made up, but it conveys the idea nicely):
 *      print("%s", intToString(123).c_str());
 * More info on rvalue references:
 *      https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
 *      http://stackoverflow.com/questions/584824/guaranteed-lifetime-of-temporary-in-c
 */
template <
    int Radix = 10,
    typename T,
    typename std::enable_if<std::is_integral<T>::value>::type...
    >
inline auto intToString(T number)
{
    constexpr char Alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";

    static_assert(Radix >= 1, "Radix must be positive");
    static_assert(Radix <= (sizeof(Alphabet) / sizeof(Alphabet[0])), "Radix is too large");

    // Plus 1 to round up, see the standard for details.
    constexpr unsigned MaxChars =
        ((Radix >= 10) ? std::numeric_limits<T>::digits10 : std::numeric_limits<T>::digits) +
        1 + (std::is_signed<T>::value ? 1 : 0);

    class Container
    {
        std::uint_fast16_t offset_;
        char storage_[MaxChars + 1];   // Plus 1 because of zero termination.

    public:
        Container(T x) :
            offset_(MaxChars)          // Field initialization is not working in GCC in this context, not sure why.
        {
            storage_[offset_] = '\0';

            do
            {
                assert(offset_ > 0);

                if (std::is_signed<T>::value)  // Should be converted to constexpr if.
                {
                    // We can't just do "x = -x", because it would break on int8_t(-128), int16_t(-32768), etc.
                    auto residual = std::int_fast8_t(x % Radix);
                    if (residual < 0)
                    {
                        // Should never happen - since C++11, neg % pos --> pos
                        residual = -residual;
                    }

                    storage_[--offset_] = Alphabet[residual];

                    // Signed integers are really tricky sometimes.
                    // We must not mix negative with positive to avoid implementation-defined behaviors.
                    x = (x < 0) ? -(x / -Radix) : (x / Radix);
                }
                else
                {
                    // Fast branch for unsigned arguments.
                    storage_[--offset_] = Alphabet[x % Radix];
                    x /= Radix;
                }
            }
            while (x != 0);

            if (std::is_signed<T>::value && (x < 0))    // Should be optimized with constexpr if.
            {
                assert(offset_ > 0);
                storage_[--offset_] = '-';
            }

            assert(offset_ < MaxChars);                 // Making sure there was no overflow.
        }

        const char* c_str() const { return &storage_[offset_]; }

        operator const char* () const { return this->c_str(); }
    };

    return Container(number);
}

/**
 * The default capacity is optimal for most embedded use cases.
 */
constexpr unsigned DefaultStringCapacity = 100;

/**
 * Heapless string that keeps all data inside a fixed length buffer.
 * The capacity of the buffer can be specified via template arguments.
 * The interface is similar to that of std::string and other standard containers.
 */
template <unsigned Capacity_ = DefaultStringCapacity>
class String
{
    static_assert(Capacity_ > 0, "Capacity must be positive");

    template <unsigned C>
    friend class String;

public:
    static constexpr unsigned Capacity = Capacity_;

private:
    unsigned len_ = 0;
    char buf_[Capacity + 1] = {};

public:
    constexpr String() { }

    String(const char* const initializer) { append(initializer); }

    template <unsigned C>
    String(const String<C>& initializer) { append(initializer); }

    /*
     * Formatting
     */
    template <typename... Args>
    auto format(Args... format_args) const
    {
        String<(DefaultStringCapacity > Capacity) ? DefaultStringCapacity : Capacity> output;

        using namespace std;
        const int res = snprintf(output.begin(), output.capacity(), this->c_str(), format_args...);
        if (res > 0)
        {
            output.len_ = std::min(output.capacity(), unsigned(res));
        }

        return output;
    }

    /*
     * std::string API
     */
    constexpr unsigned capacity() const { return Capacity; }
    constexpr unsigned max_size() const { return Capacity; }

    unsigned size()   const { return len_; }
    unsigned length() const { return len_; }

    bool empty() const { return len_ == 0; }

    const char* c_str() const { return &buf_[0]; }

    void clear() { len_ = 0; }

    template <unsigned C>
    void append(const String<C>& s)
    {
        append(s.c_str());
    }

    void append(const char* p)
    {
        while ((*p != '\0') && (len_ < Capacity))
        {
            buf_[len_++] = *p++;
        }
        buf_[len_] = '\0';
        assert(buf_[Capacity] == '\0');
    }

    void append(char p)
    {
        if (len_ < Capacity)
        {
            buf_[len_++] = p;
        }
        buf_[len_] = '\0';
        assert(buf_[Capacity] == '\0');
    }

    template <typename T>
    typename std::enable_if<std::is_integral<T>::value>::type append(const T& value)
    {
        append(intToString(value).c_str());
    }

    template <typename T>
    typename std::enable_if<std::is_floating_point<T>::value>::type append(const T& value)
    {
        constexpr int Precision = std::numeric_limits<T>::digits10 + 1;
        static_assert(Precision > 1, "Invalid floating point type?");

        char buffer[20];

        using namespace std;
        (void) snprintf(buffer, sizeof(buffer), "%.*g", Precision, double(value));

        append(static_cast<const char*>(&buffer[0]));
    }

    template <typename T>
    void concatenate(const T& head)
    {
        this->append(head);
    }

    template <typename T, typename... Args>
    void concatenate(const T& head, Args... tail)
    {
        this->append(head);
        this->concatenate(tail...);
    }

    char&       front()       { return operator[](0); }
    const char& front() const { return operator[](0); }

    char& back()
    {
        if (len_ > 0)
        {
            return buf_[len_ - 1U];
        }
        else
        {
            assert(false);
            return buf_[0];
        }
    }
    const char& back() const { return const_cast<String*>(this)->back(); }

    template <unsigned C>
    bool compare(const String<C>& s) const
    {
        return compare(s.c_str());
    }

    bool compare(const char* s) const
    {
        return 0 == std::strncmp(this->c_str(), s, Capacity);
    }

    /*
     * Iterators
     */
    const char* begin() const { return &buf_[0]; }
    const char* end()   const { return &buf_[len_]; }

    char* begin() { return &buf_[0]; }
    char* end()   { return &buf_[len_]; }

    /*
     * Operators
     */
    template <typename T>
    String& operator=(const T& s)
    {
        clear();
        append(s);
        return *this;
    }

    template <typename T>
    String& operator+=(const T& s)
    {
        append(s);
        return *this;
    }

    char& operator[](unsigned index)
    {
        if (index < len_)
        {
            return buf_[index];
        }
        else
        {
            assert(false);
            return back();
        }
    }
    const char& operator[](unsigned index) const { return const_cast<String*>(this)->operator[](index); }

    template <typename T>
    bool operator==(const T& s) const { return compare(s); }

    /*
     * Helpers
     */
    template <typename Left, typename Right>
    static auto join(const Left& left, const Right& right)
    {
        String<(DefaultStringCapacity > Capacity) ? DefaultStringCapacity : Capacity> output(left);
        output.append(right);
        return output;
    }

    struct Formatter
    {
        String<Capacity> format_string;

        Formatter(const char* format_string) : format_string(format_string) { }

        template <typename... Args>
        auto operator()(Args... format_args)
        {
            return format_string.format(format_args...);
        }
    };
};

/**
 * Operators for String<>.
 * @{
 */
template <unsigned LeftCapacity, unsigned RightCapacity>
inline auto operator+(const String<LeftCapacity>& left, const String<RightCapacity>& right)
{
    return String<LeftCapacity + RightCapacity>::join(left, right);
}

template <unsigned Capacity>
inline auto operator+(const String<Capacity>& left, const char* right)
{
    return String<Capacity>::join(left, right);
}

template <unsigned Capacity>
inline auto operator+(const char* left, const String<Capacity>& right)
{
    return String<Capacity>::join(left, right);
}

template <unsigned Capacity>
inline bool operator==(const char* left, const String<Capacity>& right)
{
    return right.compare(left);
}
/**
 * @}
 */

/**
 * Converts a string literal into String<>.
 * Usage example:
 *      auto len = "Hello world!"_heapless.length();
 */
inline auto operator "" _heapless(const char* str, std::size_t)
{
    return String<>(str);
}

/**
 * Formats a string literal using heapless string.
 * Usage example:
 *      auto str = "The %s answer is %d!"_format("Great", 42);
 */
inline auto operator "" _format(const char* str, std::size_t)
{
    return String<>::Formatter(str);
}

/**
 * Formats an arbitrary string and returns it as a heapless string instance.
 * Usage example:
 *      conat auto str = format("The %s answer is %d!", "Great", 42);
 */
template<unsigned FormatLength, typename... Args>
inline auto format(const char (&format_string)[FormatLength], Args... format_args)
{
    return String<FormatLength>(format_string).format(format_args...);
}

/**
 * Like Python's print(), except that it returns the string by value as a heapless instance instead of
 * printing it.
 * Usage example:
 *      auto str = concatenate("The Great Answer is", 42, "!\n");
 */
template <unsigned Capacity = DefaultStringCapacity, typename... Args>
inline auto concatenate(Args... arguments)
{
    String<Capacity> s;
    s.concatenate(arguments...);
    return s;
}

/**
 * Compatibility with standard streams, nothing special here.
 */
template <typename Stream, unsigned Capacity>
inline Stream& operator<<(Stream& stream, const String<Capacity>& obj)
{
    stream << obj.c_str();
    return stream;
}

}
}
<commit_msg>Increased default string capacity<commit_after>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

/*
 * Collection of heap-less containers and functions.
 */

#pragma once

#include <type_traits>
#include <algorithm>
#include <cassert>
#include <cstdarg>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <limits>

namespace os
{
namespace heapless
{
/**
 * Converts any signed or unsigned integer or boolean to string and returns it by value.
 * The argument must be of integral type, otherwise the call will be rejected by SFINAE.
 * Usage examples:
 *      intToString(var)
 *      intToString<16>(var)
 *      intToString<2>(var).c_str()
 * It is safe to obtain a reference to the returned string and pass it to another function as an argument,
 * which enables use cases like this (this example is somewhat made up, but it conveys the idea nicely):
 *      print("%s", intToString(123).c_str());
 * More info on rvalue references:
 *      https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
 *      http://stackoverflow.com/questions/584824/guaranteed-lifetime-of-temporary-in-c
 */
template <
    int Radix = 10,
    typename T,
    typename std::enable_if<std::is_integral<T>::value>::type...
    >
inline auto intToString(T number)
{
    constexpr char Alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";

    static_assert(Radix >= 1, "Radix must be positive");
    static_assert(Radix <= (sizeof(Alphabet) / sizeof(Alphabet[0])), "Radix is too large");

    // Plus 1 to round up, see the standard for details.
    constexpr unsigned MaxChars =
        ((Radix >= 10) ? std::numeric_limits<T>::digits10 : std::numeric_limits<T>::digits) +
        1 + (std::is_signed<T>::value ? 1 : 0);

    class Container
    {
        std::uint_fast16_t offset_;
        char storage_[MaxChars + 1];   // Plus 1 because of zero termination.

    public:
        Container(T x) :
            offset_(MaxChars)          // Field initialization is not working in GCC in this context, not sure why.
        {
            storage_[offset_] = '\0';

            do
            {
                assert(offset_ > 0);

                if (std::is_signed<T>::value)  // Should be converted to constexpr if.
                {
                    // We can't just do "x = -x", because it would break on int8_t(-128), int16_t(-32768), etc.
                    auto residual = std::int_fast8_t(x % Radix);
                    if (residual < 0)
                    {
                        // Should never happen - since C++11, neg % pos --> pos
                        residual = -residual;
                    }

                    storage_[--offset_] = Alphabet[residual];

                    // Signed integers are really tricky sometimes.
                    // We must not mix negative with positive to avoid implementation-defined behaviors.
                    x = (x < 0) ? -(x / -Radix) : (x / Radix);
                }
                else
                {
                    // Fast branch for unsigned arguments.
                    storage_[--offset_] = Alphabet[x % Radix];
                    x /= Radix;
                }
            }
            while (x != 0);

            if (std::is_signed<T>::value && (x < 0))    // Should be optimized with constexpr if.
            {
                assert(offset_ > 0);
                storage_[--offset_] = '-';
            }

            assert(offset_ < MaxChars);                 // Making sure there was no overflow.
        }

        const char* c_str() const { return &storage_[offset_]; }

        operator const char* () const { return this->c_str(); }
    };

    return Container(number);
}

/**
 * The default capacity is optimal for most embedded use cases.
 */
constexpr unsigned DefaultStringCapacity = 200;

/**
 * Heapless string that keeps all data inside a fixed length buffer.
 * The capacity of the buffer can be specified via template arguments.
 * The interface is similar to that of std::string and other standard containers.
 */
template <unsigned Capacity_ = DefaultStringCapacity>
class String
{
    static_assert(Capacity_ > 0, "Capacity must be positive");

    template <unsigned C>
    friend class String;

public:
    static constexpr unsigned Capacity = Capacity_;

private:
    unsigned len_ = 0;
    char buf_[Capacity + 1] = {};

public:
    constexpr String() { }

    String(const char* const initializer) { append(initializer); }

    template <unsigned C>
    String(const String<C>& initializer) { append(initializer); }

    /*
     * Formatting
     */
    template <typename... Args>
    auto format(Args... format_args) const
    {
        String<(DefaultStringCapacity > Capacity) ? DefaultStringCapacity : Capacity> output;

        using namespace std;
        const int res = snprintf(output.begin(), output.capacity(), this->c_str(), format_args...);
        if (res > 0)
        {
            output.len_ = std::min(output.capacity(), unsigned(res));
        }

        return output;
    }

    /*
     * std::string API
     */
    constexpr unsigned capacity() const { return Capacity; }
    constexpr unsigned max_size() const { return Capacity; }

    unsigned size()   const { return len_; }
    unsigned length() const { return len_; }

    bool empty() const { return len_ == 0; }

    const char* c_str() const { return &buf_[0]; }

    void clear() { len_ = 0; }

    template <unsigned C>
    void append(const String<C>& s)
    {
        append(s.c_str());
    }

    void append(const char* p)
    {
        while ((*p != '\0') && (len_ < Capacity))
        {
            buf_[len_++] = *p++;
        }
        buf_[len_] = '\0';
        assert(buf_[Capacity] == '\0');
    }

    void append(char p)
    {
        if (len_ < Capacity)
        {
            buf_[len_++] = p;
        }
        buf_[len_] = '\0';
        assert(buf_[Capacity] == '\0');
    }

    template <typename T>
    typename std::enable_if<std::is_integral<T>::value>::type append(const T& value)
    {
        append(intToString(value).c_str());
    }

    template <typename T>
    typename std::enable_if<std::is_floating_point<T>::value>::type append(const T& value)
    {
        constexpr int Precision = std::numeric_limits<T>::digits10 + 1;
        static_assert(Precision > 1, "Invalid floating point type?");

        char buffer[20];

        using namespace std;
        (void) snprintf(buffer, sizeof(buffer), "%.*g", Precision, double(value));

        append(static_cast<const char*>(&buffer[0]));
    }

    template <typename T>
    void concatenate(const T& head)
    {
        this->append(head);
    }

    template <typename T, typename... Args>
    void concatenate(const T& head, Args... tail)
    {
        this->append(head);
        this->concatenate(tail...);
    }

    char&       front()       { return operator[](0); }
    const char& front() const { return operator[](0); }

    char& back()
    {
        if (len_ > 0)
        {
            return buf_[len_ - 1U];
        }
        else
        {
            assert(false);
            return buf_[0];
        }
    }
    const char& back() const { return const_cast<String*>(this)->back(); }

    template <unsigned C>
    bool compare(const String<C>& s) const
    {
        return compare(s.c_str());
    }

    bool compare(const char* s) const
    {
        return 0 == std::strncmp(this->c_str(), s, Capacity);
    }

    /*
     * Iterators
     */
    const char* begin() const { return &buf_[0]; }
    const char* end()   const { return &buf_[len_]; }

    char* begin() { return &buf_[0]; }
    char* end()   { return &buf_[len_]; }

    /*
     * Operators
     */
    template <typename T>
    String& operator=(const T& s)
    {
        clear();
        append(s);
        return *this;
    }

    template <typename T>
    String& operator+=(const T& s)
    {
        append(s);
        return *this;
    }

    char& operator[](unsigned index)
    {
        if (index < len_)
        {
            return buf_[index];
        }
        else
        {
            assert(false);
            return back();
        }
    }
    const char& operator[](unsigned index) const { return const_cast<String*>(this)->operator[](index); }

    template <typename T>
    bool operator==(const T& s) const { return compare(s); }

    /*
     * Helpers
     */
    template <typename Left, typename Right>
    static auto join(const Left& left, const Right& right)
    {
        String<(DefaultStringCapacity > Capacity) ? DefaultStringCapacity : Capacity> output(left);
        output.append(right);
        return output;
    }

    struct Formatter
    {
        String<Capacity> format_string;

        Formatter(const char* format_string) : format_string(format_string) { }

        template <typename... Args>
        auto operator()(Args... format_args)
        {
            return format_string.format(format_args...);
        }
    };
};

/**
 * Operators for String<>.
 * @{
 */
template <unsigned LeftCapacity, unsigned RightCapacity>
inline auto operator+(const String<LeftCapacity>& left, const String<RightCapacity>& right)
{
    return String<LeftCapacity + RightCapacity>::join(left, right);
}

template <unsigned Capacity>
inline auto operator+(const String<Capacity>& left, const char* right)
{
    return String<Capacity>::join(left, right);
}

template <unsigned Capacity>
inline auto operator+(const char* left, const String<Capacity>& right)
{
    return String<Capacity>::join(left, right);
}

template <unsigned Capacity>
inline bool operator==(const char* left, const String<Capacity>& right)
{
    return right.compare(left);
}
/**
 * @}
 */

/**
 * Converts a string literal into String<>.
 * Usage example:
 *      auto len = "Hello world!"_heapless.length();
 */
inline auto operator "" _heapless(const char* str, std::size_t)
{
    return String<>(str);
}

/**
 * Formats a string literal using heapless string.
 * Usage example:
 *      auto str = "The %s answer is %d!"_format("Great", 42);
 */
inline auto operator "" _format(const char* str, std::size_t)
{
    return String<>::Formatter(str);
}

/**
 * Formats an arbitrary string and returns it as a heapless string instance.
 * Usage example:
 *      conat auto str = format("The %s answer is %d!", "Great", 42);
 */
template<unsigned FormatLength, typename... Args>
inline auto format(const char (&format_string)[FormatLength], Args... format_args)
{
    return String<FormatLength>(format_string).format(format_args...);
}

/**
 * Like Python's print(), except that it returns the string by value as a heapless instance instead of
 * printing it.
 * Usage example:
 *      auto str = concatenate("The Great Answer is", 42, "!\n");
 */
template <unsigned Capacity = DefaultStringCapacity, typename... Args>
inline auto concatenate(Args... arguments)
{
    String<Capacity> s;
    s.concatenate(arguments...);
    return s;
}

/**
 * Compatibility with standard streams, nothing special here.
 */
template <typename Stream, unsigned Capacity>
inline Stream& operator<<(Stream& stream, const String<Capacity>& obj)
{
    stream << obj.c_str();
    return stream;
}

}
}
<|endoftext|>


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

//\author: Blaise Gassend

#include <unistd.h>
#include <math.h>
#include <linux/joystick.h>
#include <fcntl.h>
#include <ros/ros.h>
#include <diagnostic_updater/diagnostic_updater.h>
#include <sensor_msgs/Joy.h>

///\brief Opens, reads from and publishes joystick events
class Joystick
{
private:
  ros::NodeHandle nh_;
  bool open_;
  std::string joy_dev_;
  double deadzone_;
  double autorepeat_rate_;  // in Hz.  0 for no repeat.
  double coalesce_interval_; // Defaults to 100 Hz rate limit.
  int event_count_;
  int pub_count_;
  ros::Publisher pub_;
  double lastDiagTime_;

  diagnostic_updater::Updater diagnostic_;

  ///\brief Publishes diagnostics and status
  void diagnostics(diagnostic_updater::DiagnosticStatusWrapper& stat)
  {
    double now = ros::Time::now().toSec();
    double interval = now - lastDiagTime_;
    if (open_)
      stat.summary(0, "OK");
    else
      stat.summary(2, "Joystick not open.");

    stat.add("topic", pub_.getTopic());
    stat.add("device", joy_dev_);
    stat.add("dead zone", deadzone_);
    stat.add("autorepeat rate (Hz)", autorepeat_rate_);
    stat.add("coalesce interval (s)", coalesce_interval_);
    stat.add("recent joystick event rate (Hz)", event_count_ / interval);
    stat.add("recent publication rate (Hz)", pub_count_ / interval);
    stat.add("subscribers", pub_.getNumSubscribers());
    event_count_ = 0;
    pub_count_ = 0;
    lastDiagTime_ = now;
  }

public:
  Joystick() : nh_(), diagnostic_()
  {}

  ///\brief Opens joystick port, reads from port and publishes while node is active
  int main(int argc, char **argv)
  {
    diagnostic_.add("Joystick Driver Status", this, &Joystick::diagnostics);
    diagnostic_.setHardwareID("none");

    // Parameters
    ros::NodeHandle nh_param("~");

    std::string pub_topic;
    nh_param.param<std::string>("topic", pub_topic, "joy");

    pub_ = nh_.advertise<sensor_msgs::Joy>(pub_topic, 1);

    nh_param.param<std::string>("dev", joy_dev_, "/dev/input/js0");
    nh_param.param<double>("deadzone", deadzone_, 0.05);
    nh_param.param<double>("autorepeat_rate", autorepeat_rate_, 0);
    nh_param.param<double>("coalesce_interval", coalesce_interval_, 0.001);

    // Checks on parameters
    if (autorepeat_rate_ > 1 / coalesce_interval_)
      ROS_WARN("joy_node: autorepeat_rate (%f Hz) > 1/coalesce_interval (%f Hz) does not make sense. Timing behavior is not well defined.", autorepeat_rate_, 1/coalesce_interval_);

    if (deadzone_ >= 1)
    {
      ROS_WARN("joy_node: deadzone greater than 1 was requested. The semantics of deadzone have changed. It is now related to the range [-1:1] instead of [-32767:32767]. For now I am dividing your deadzone by 32767, but this behavior is deprecated so you need to update your launch file.");
      deadzone_ /= 32767;
    }

    if (deadzone_ > 0.9)
    {
      ROS_WARN("joy_node: deadzone (%f) greater than 0.9, setting it to 0.9", deadzone_);
      deadzone_ = 0.9;
    }

    if (deadzone_ < 0)
    {
      ROS_WARN("joy_node: deadzone_ (%f) less than 0, setting to 0.", deadzone_);
      deadzone_ = 0;
    }

    if (autorepeat_rate_ < 0)
    {
      ROS_WARN("joy_node: autorepeat_rate (%f) less than 0, setting to 0.", autorepeat_rate_);
      autorepeat_rate_ = 0;
    }

    if (coalesce_interval_ < 0)
    {
      ROS_WARN("joy_node: coalesce_interval (%f) less than 0, setting to 0.", coalesce_interval_);
      coalesce_interval_ = 0;
    }

    // Parameter conversions
    double autorepeat_interval = 1 / autorepeat_rate_;
    double scale = -1. / (1. - deadzone_) / 32767.;
    double unscaled_deadzone = 32767. * deadzone_;

    js_event event;
    struct timeval tv;
    fd_set set;
    int joy_fd;
    event_count_ = 0;
    pub_count_ = 0;
    lastDiagTime_ = ros::Time::now().toSec();

    // Big while loop opens, publishes
    while (nh_.ok())
    {
      open_ = false;
      diagnostic_.force_update();
      bool first_fault = true;
      while (true)
      {
        ros::spinOnce();
        if (!nh_.ok())
          goto cleanup;
        joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        if (joy_fd != -1)
        {
          // There seems to be a bug in the driver or something where the
          // initial events that are to define the initial state of the
          // joystick are not the values of the joystick when it was opened
          // but rather the values of the joystick when it was last closed.
          // Opening then closing and opening again is a hack to get more
          // accurate initial state data.
          close(joy_fd);
          joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        }
        if (joy_fd != -1)
          break;
        if (first_fault)
        {
          ROS_ERROR("Couldn't open joystick %s. Will retry every second.", joy_dev_.c_str());
          first_fault = false;
        }
        sleep(1.0);
        diagnostic_.update();
      }

      ROS_INFO("Opened joystick: %s. deadzone_: %f.", joy_dev_.c_str(), deadzone_);
      open_ = true;
      diagnostic_.force_update();

      bool tv_set = false;
      bool publication_pending = false;
      tv.tv_sec = 1;
      tv.tv_usec = 0;
      sensor_msgs::Joy joy_msg; // Here because we want to reset it on device close.
      while (nh_.ok())
      {
        ros::spinOnce();

        bool publish_now = false;
        bool publish_soon = false;
        FD_ZERO(&set);
        FD_SET(joy_fd, &set);

        //ROS_INFO("Select...");
        int select_out = select(joy_fd+1, &set, NULL, NULL, &tv);
        //ROS_INFO("Tick...");
        if (select_out == -1)
        {
          tv.tv_sec = 0;
          tv.tv_usec = 0;
          //ROS_INFO("Select returned negative. %i", ros::isShuttingDown());
          continue;
          //				break; // Joystick is probably closed. Not sure if this case is useful.
        }

        if (FD_ISSET(joy_fd, &set))
        {
          if (read(joy_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
            break; // Joystick is probably closed. Definitely occurs.

          //ROS_INFO("Read data...");
          joy_msg.header.stamp = ros::Time().now();
          event_count_++;
          switch(event.type)
          {
          case JS_EVENT_BUTTON:
          case JS_EVENT_BUTTON | JS_EVENT_INIT:
            if(event.number >= joy_msg.buttons.size())
            {
              int old_size = joy_msg.buttons.size();
              joy_msg.buttons.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.buttons.size();i++)
                joy_msg.buttons[i] = 0.0;
            }
            joy_msg.buttons[event.number] = (event.value ? 1 : 0);
            // For initial events, wait a bit before sending to try to catch
            // all the initial events.
            if (!(event.type & JS_EVENT_INIT))
              publish_now = true;
            else
              publish_soon = true;
            break;
          case JS_EVENT_AXIS:
          case JS_EVENT_AXIS | JS_EVENT_INIT:
            if(event.number >= joy_msg.axes.size())
            {
              int old_size = joy_msg.axes.size();
              joy_msg.axes.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.axes.size();i++)
                joy_msg.axes[i] = 0.0;
            }
            if (!(event.type & JS_EVENT_INIT)) // Init event.value is wrong.
            {
              double val = event.value;
              // Allows deadzone to be "smooth"
              if (val > unscaled_deadzone)
                val -= unscaled_deadzone;
              else if (val < -unscaled_deadzone)
                val += unscaled_deadzone;
              else
                val = 0;
              joy_msg.axes[event.number] = val * scale;
            }
            // Will wait a bit before sending to try to combine events.
            publish_soon = true;
            break;
          default:
            ROS_WARN("joy_node: Unknown event type. Please file a ticket. time=%u, value=%d, type=%Xh, number=%d", event.time, event.value, event.type, event.number);
            break;
          }
        }
        else if (tv_set) // Assume that the timer has expired.
          publish_now = true;

        if (publish_now)
        {
          // Assume that all the JS_EVENT_INIT messages have arrived already.
          // This should be the case as the kernel sends them along as soon as
          // the device opens.
          //ROS_INFO("Publish...");
          pub_.publish(joy_msg);
          publish_now = false;
          tv_set = false;
          publication_pending = false;
          publish_soon = false;
          pub_count_++;
        }

        // If an axis event occurred, start a timer to combine with other
        // events.
        if (!publication_pending && publish_soon)
        {
          tv.tv_sec = trunc(coalesce_interval_);
          tv.tv_usec = (coalesce_interval_ - tv.tv_sec) * 1e6;
          publication_pending = true;
          tv_set = true;
          //ROS_INFO("Pub pending...");
        }

        // If nothing is going on, start a timer to do autorepeat.
        if (!tv_set && autorepeat_rate_ > 0)
        {
          tv.tv_sec = trunc(autorepeat_interval);
          tv.tv_usec = (autorepeat_interval - tv.tv_sec) * 1e6;
          tv_set = true;
          //ROS_INFO("Autorepeat pending... %i %i", tv.tv_sec, tv.tv_usec);
        }

        if (!tv_set)
        {
          tv.tv_sec = 1;
          tv.tv_usec = 0;
        }

        diagnostic_.update();
      } // End of joystick open loop.

      close(joy_fd);
      ros::spinOnce();
      if (nh_.ok())
        ROS_ERROR("Connection to joystick device lost unexpectedly. Will reopen.");
    }

  cleanup:
    ROS_INFO("joy_node shut down.");

    return 0;
  }
};

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

//\author: Blaise Gassend

#include <unistd.h>
#include <math.h>
#include <linux/joystick.h>
#include <fcntl.h>
#include <ros/ros.h>
#include <sensor_msgs/Joy.h>
#include <geometry_msgs/Twist.h>

///\brief Opens, reads from and publishes joystick events
class Joystick
{
private:
  ros::NodeHandle nh_;
  bool open_;
  std::string joy_dev_;
  double deadzone_;
  double autorepeat_rate_;  // in Hz.  0 for no repeat.
  double coalesce_interval_; // Defaults to 100 Hz rate limit.
  int event_count_;
  int pub_count_;
  double lastDiagTime_;

  double a_scale_;
  double l_scale_;
  ros::Publisher velocity_publisher_;
  ros::Timer velocity_publish_timer_;
  sensor_msgs::Joy current_joy_message_;

  void publish_velocity(ros::TimerEvent event) {
	  geometry_msgs::Twist vel;
	  vel.angular.z = a_scale_ * current_joy_message_.axes[3];
	  vel.linear.x = l_scale_ * current_joy_message_.axes[4];
	  velocity_publisher_.publish(vel);
  }

public:
  Joystick() : nh_() {}

  ///\brief Opens joystick port, reads from port and publishes while node is active
  int main(int argc, char **argv)
  {
//    diagnostic_.add("Joystick Driver Status", this, &Joystick::diagnostics);
//    diagnostic_.setHardwareID("none");

    // Parameters
    ros::NodeHandle nh_param("~");

    std::string pub_topic;
    nh_param.param<std::string>("topic", pub_topic, "joy");

    // pub_ = nh_.advertise<sensor_msgs::Joy>(pub_topic, 1);
    velocity_publisher_ = nh_.advertise<geometry_msgs::Twist>("/joy_cmd_vel", 100, false);
    velocity_publish_timer_ = nh_.createTimer(ros::Duration(0.1), boost::bind(&Joystick::publish_velocity, this, _1));

    nh_param.param<std::string>("dev", joy_dev_, "/dev/input/js0");
    nh_param.param<double>("deadzone", deadzone_, 0.05);
    nh_param.param<double>("autorepeat_rate", autorepeat_rate_, 0);
    nh_param.param<double>("coalesce_interval", coalesce_interval_, 0.001);

    nh_param.param("scale_angular", a_scale_, 0.9);
    nh_param.param("scale_linear" , l_scale_, 2.0);

    // Checks on parameters
    if (autorepeat_rate_ > 1 / coalesce_interval_)
      ROS_WARN("joy_node: autorepeat_rate (%f Hz) > 1/coalesce_interval (%f Hz) does not make sense. Timing behavior is not well defined.", autorepeat_rate_, 1/coalesce_interval_);

    if (deadzone_ >= 1)
    {
      ROS_WARN("joy_node: deadzone greater than 1 was requested. The semantics of deadzone have changed. It is now related to the range [-1:1] instead of [-32767:32767]. For now I am dividing your deadzone by 32767, but this behavior is deprecated so you need to update your launch file.");
      deadzone_ /= 32767;
    }

    if (deadzone_ > 0.9)
    {
      ROS_WARN("joy_node: deadzone (%f) greater than 0.9, setting it to 0.9", deadzone_);
      deadzone_ = 0.9;
    }

    if (deadzone_ < 0)
    {
      ROS_WARN("joy_node: deadzone_ (%f) less than 0, setting to 0.", deadzone_);
      deadzone_ = 0;
    }

    if (autorepeat_rate_ < 0)
    {
      ROS_WARN("joy_node: autorepeat_rate (%f) less than 0, setting to 0.", autorepeat_rate_);
      autorepeat_rate_ = 0;
    }

    if (coalesce_interval_ < 0)
    {
      ROS_WARN("joy_node: coalesce_interval (%f) less than 0, setting to 0.", coalesce_interval_);
      coalesce_interval_ = 0;
    }

    // Parameter conversions
    double autorepeat_interval = 1 / autorepeat_rate_;
    double scale = -1. / (1. - deadzone_) / 32767.;
    double unscaled_deadzone = 32767. * deadzone_;

    js_event event;
    struct timeval tv;
    fd_set set;
    int joy_fd;
    event_count_ = 0;
    pub_count_ = 0;
    lastDiagTime_ = ros::Time::now().toSec();

    // Big while loop opens, publishes
    while (nh_.ok())
    {
      open_ = false;
//      diagnostic_.force_update();
      bool first_fault = true;
      while (true)
      {
        ros::spinOnce();
        if (!nh_.ok())
          goto cleanup;
        joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        if (joy_fd != -1)
        {
          // There seems to be a bug in the driver or something where the
          // initial events that are to define the initial state of the
          // joystick are not the values of the joystick when it was opened
          // but rather the values of the joystick when it was last closed.
          // Opening then closing and opening again is a hack to get more
          // accurate initial state data.
          close(joy_fd);
          joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        }
        if (joy_fd != -1)
          break;
        if (first_fault)
        {
          ROS_ERROR("Couldn't open joystick %s. Will retry every second.", joy_dev_.c_str());
          first_fault = false;
        }
        sleep(1.0);
//        diagnostic_.update();
      }

      ROS_INFO("Opened joystick: %s. deadzone_: %f.", joy_dev_.c_str(), deadzone_);
      open_ = true;
//      diagnostic_.force_update();

      bool tv_set = false;
      bool publication_pending = false;
      tv.tv_sec = 1;
      tv.tv_usec = 0;
      sensor_msgs::Joy joy_msg; // Here because we want to reset it on device close.
      while (nh_.ok())
      {
        ros::spinOnce();

        bool publish_now = false;
        bool publish_soon = false;
        FD_ZERO(&set);
        FD_SET(joy_fd, &set);

        //ROS_INFO("Select...");
        int select_out = select(joy_fd+1, &set, NULL, NULL, &tv);
        //ROS_INFO("Tick...");
        if (select_out == -1)
        {
          tv.tv_sec = 0;
          tv.tv_usec = 0;
          //ROS_INFO("Select returned negative. %i", ros::isShuttingDown());
          continue;
          //				break; // Joystick is probably closed. Not sure if this case is useful.
        }

        if (FD_ISSET(joy_fd, &set))
        {
          if (read(joy_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
            break; // Joystick is probably closed. Definitely occurs.

          //ROS_INFO("Read data...");
          joy_msg.header.stamp = ros::Time().now();
          event_count_++;
          switch(event.type)
          {
          case JS_EVENT_BUTTON:
          case JS_EVENT_BUTTON | JS_EVENT_INIT:
            if(event.number >= joy_msg.buttons.size())
            {
              int old_size = joy_msg.buttons.size();
              joy_msg.buttons.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.buttons.size();i++)
                joy_msg.buttons[i] = 0.0;
            }
            joy_msg.buttons[event.number] = (event.value ? 1 : 0);
            // For initial events, wait a bit before sending to try to catch
            // all the initial events.
            if (!(event.type & JS_EVENT_INIT))
              publish_now = true;
            else
              publish_soon = true;
            break;
          case JS_EVENT_AXIS:
          case JS_EVENT_AXIS | JS_EVENT_INIT:
            if(event.number >= joy_msg.axes.size())
            {
              int old_size = joy_msg.axes.size();
              joy_msg.axes.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.axes.size();i++)
                joy_msg.axes[i] = 0.0;
            }
            if (!(event.type & JS_EVENT_INIT)) // Init event.value is wrong.
            {
              double val = event.value;
              // Allows deadzone to be "smooth"
              if (val > unscaled_deadzone)
                val -= unscaled_deadzone;
              else if (val < -unscaled_deadzone)
                val += unscaled_deadzone;
              else
                val = 0;
              joy_msg.axes[event.number] = val * scale;
            }
            // Will wait a bit before sending to try to combine events.
            publish_soon = true;
            break;
          default:
            ROS_WARN("joy_node: Unknown event type. Please file a ticket. time=%u, value=%d, type=%Xh, number=%d", event.time, event.value, event.type, event.number);
            break;
          }
        }
        else if (tv_set) // Assume that the timer has expired.
          publish_now = true;

        if (publish_now)
        {
          // Assume that all the JS_EVENT_INIT messages have arrived already.
          // This should be the case as the kernel sends them along as soon as
          // the device opens.
          //ROS_INFO("Publish...");

          // pub_.publish(joy_msg);
        	current_joy_message_ = joy_msg;
          publish_now = false;
          tv_set = false;
          publication_pending = false;
          publish_soon = false;
          pub_count_++;
        }

        // If an axis event occurred, start a timer to combine with other
        // events.
        if (!publication_pending && publish_soon)
        {
          tv.tv_sec = trunc(coalesce_interval_);
          tv.tv_usec = (coalesce_interval_ - tv.tv_sec) * 1e6;
          publication_pending = true;
          tv_set = true;
          //ROS_INFO("Pub pending...");
        }

        // If nothing is going on, start a timer to do autorepeat.
        if (!tv_set && autorepeat_rate_ > 0)
        {
          tv.tv_sec = trunc(autorepeat_interval);
          tv.tv_usec = (autorepeat_interval - tv.tv_sec) * 1e6;
          tv_set = true;
          //ROS_INFO("Autorepeat pending... %i %i", tv.tv_sec, tv.tv_usec);
        }

        if (!tv_set)
        {
          tv.tv_sec = 1;
          tv.tv_usec = 0;
        }

//        diagnostic_.update();
      } // End of joystick open loop.

      close(joy_fd);
      ros::spinOnce();
      if (nh_.ok())
        ROS_ERROR("Connection to joystick device lost unexpectedly. Will reopen.");
    }

  cleanup:
    ROS_INFO("joy_node shut down.");

    return 0;
  }
};

int main(int argc, char **argv)
{
  ros::init(argc, argv, "joy_node");
  Joystick j;
  return j.main(argc, argv);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "ut_mtapandholdrecognizer.h"
#include "mtapandholdrecognizer.h"
#include "mtapandholdrecognizer_p.h"

#include "mtapandholdgesture_p.h"

#include "mapplication.h"
#include <QGraphicsView>
#include <QMouseEvent>
#include <QtTest/QtTest>

int startTimerInterval;
int QObject::startTimer(int interval)
{
    startTimerInterval = interval;
    return 1;
}

Qt::GestureState currentGestureState = Qt::NoGesture;
Qt::GestureState QGesture::state() const
{
    return currentGestureState;
}

//Mocking MThemePrivate, because the style object is private to library
//and we need to compile some functionality into the unittest.
#include "mtheme_p.h"
void MThemePrivate::unregisterStyleContainer(MStyleContainer*)
{
}

void MThemePrivate::registerStyleContainer(MStyleContainer *)
{
}

#include "mtheme.h"
//Filling the values of the style object.
static const int MTapAndHoldSetTimeout = 200; /* miliseconds */
static const int MTapAndHoldStyleTimeout = 500; /* miliseconds */
static const qreal MTapAndHoldMovementThreshold = 20; /* pixels */

MTapAndHoldRecognizerStyle recognizerStyle;
const MStyle *MTheme::style(const char *,
                            const QString &) {
    recognizerStyle.setTimeout(MTapAndHoldStyleTimeout);
    recognizerStyle.setMovementThreshold(MTapAndHoldMovementThreshold);
    return &recognizerStyle;
}

void MTheme::releaseStyle(const MStyle *)
{
}

MApplication *app;
QGraphicsView *view;
void Ut_MTapAndHoldRecognizer::initTestCase()
{
    static int argc = 1;
    static char *app_name[1] = { (char *) "./ut_mtapandholdrecognizer" };
    app = new MApplication(argc, app_name);

    view = new QGraphicsView();
    view->show();
}

void Ut_MTapAndHoldRecognizer::cleanupTestCase()
{
    delete app;
}

void Ut_MTapAndHoldRecognizer::init()
{
    startTimerInterval = -1;

    recognizer = new MTapAndHoldRecognizer();
}

void Ut_MTapAndHoldRecognizer::cleanup()
{
    delete recognizer;
}

void Ut_MTapAndHoldRecognizer::testCreateGesture()
{
    tapAndHoldGesture = static_cast<MTapAndHoldGesture*>(recognizer->create(view));
}

void Ut_MTapAndHoldRecognizer::testRecognize()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    QTimerEvent fakeTimerEvent(tapAndHoldGesture->timerId);
    currentState = recognizer->recognize(tapAndHoldGesture, tapAndHoldGesture, &fakeTimerEvent);
    QCOMPARE( currentState, QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint );

    delete pressEvent;
}

void Ut_MTapAndHoldRecognizer::testFastTap()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    //Setting timerId as would happen in real life scenario
    tapAndHoldGesture->timerId = 1;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, releaseEvent);
    QCOMPARE( currentState, QGestureRecognizer::CancelGesture);

    delete pressEvent;
    delete releaseEvent;
}

void Ut_MTapAndHoldRecognizer::testMovePointerInsideThreshold()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *moveEvent = new QMouseEvent(QEvent::MouseMove, QPoint(3,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    currentGestureState = Qt::GestureStarted;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, moveEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    QTimerEvent fakeTimerEvent(tapAndHoldGesture->timerId);
    currentState = recognizer->recognize(tapAndHoldGesture, tapAndHoldGesture, &fakeTimerEvent);
    QCOMPARE( currentState, QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint );

    delete pressEvent;
    delete moveEvent;
}

void Ut_MTapAndHoldRecognizer::testMovePointerBeyondThreshold()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *moveEvent = new QMouseEvent(QEvent::MouseMove, QPoint(50,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    currentGestureState = Qt::GestureStarted;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, moveEvent);
    QCOMPARE( currentState, QGestureRecognizer::CancelGesture);

    delete pressEvent;
    delete moveEvent;
}

void Ut_MTapAndHoldRecognizer::testUsingStyleTimeout()
{
    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);

    // Verify that timeout from style is used when no timeout is set
    QCOMPARE(startTimerInterval, MTapAndHoldStyleTimeout);
}

void Ut_MTapAndHoldRecognizer::testSetTimeout()
{
    QTapAndHoldGesture::setTimeout(MTapAndHoldSetTimeout);

    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);

    // Verify that timeout that was set is used
    QCOMPARE(startTimerInterval, MTapAndHoldSetTimeout);
}

void Ut_MTapAndHoldRecognizer::testResetTimeout()
{
    QTapAndHoldGesture::setTimeout(MTapAndHoldSetTimeout);

    // Reset timeout
    QTapAndHoldGesture::setTimeout(-1);

    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);

    // Verify that as timeout was resetted then timeout from style is used
    QCOMPARE(startTimerInterval, MTapAndHoldStyleTimeout);
}

QTEST_APPLESS_MAIN(Ut_MTapAndHoldRecognizer)

<commit_msg>Changes: More sensitive build in OBS forces unused variables check RevBy:TrustMe Details:<commit_after>/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "ut_mtapandholdrecognizer.h"
#include "mtapandholdrecognizer.h"
#include "mtapandholdrecognizer_p.h"

#include "mtapandholdgesture_p.h"

#include "mapplication.h"
#include <QGraphicsView>
#include <QMouseEvent>
#include <QtTest/QtTest>

int startTimerInterval;
int QObject::startTimer(int interval)
{
    startTimerInterval = interval;
    return 1;
}

Qt::GestureState currentGestureState = Qt::NoGesture;
Qt::GestureState QGesture::state() const
{
    return currentGestureState;
}

//Mocking MThemePrivate, because the style object is private to library
//and we need to compile some functionality into the unittest.
#include "mtheme_p.h"
void MThemePrivate::unregisterStyleContainer(MStyleContainer*)
{
}

void MThemePrivate::registerStyleContainer(MStyleContainer *)
{
}

#include "mtheme.h"
//Filling the values of the style object.
static const int MTapAndHoldSetTimeout = 200; /* miliseconds */
static const int MTapAndHoldStyleTimeout = 500; /* miliseconds */
static const qreal MTapAndHoldMovementThreshold = 20; /* pixels */

MTapAndHoldRecognizerStyle recognizerStyle;
const MStyle *MTheme::style(const char *,
                            const QString &) {
    recognizerStyle.setTimeout(MTapAndHoldStyleTimeout);
    recognizerStyle.setMovementThreshold(MTapAndHoldMovementThreshold);
    return &recognizerStyle;
}

void MTheme::releaseStyle(const MStyle *)
{
}

MApplication *app;
QGraphicsView *view;
void Ut_MTapAndHoldRecognizer::initTestCase()
{
    static int argc = 1;
    static char *app_name[1] = { (char *) "./ut_mtapandholdrecognizer" };
    app = new MApplication(argc, app_name);

    view = new QGraphicsView();
    view->show();
}

void Ut_MTapAndHoldRecognizer::cleanupTestCase()
{
    delete app;
}

void Ut_MTapAndHoldRecognizer::init()
{
    startTimerInterval = -1;

    recognizer = new MTapAndHoldRecognizer();
}

void Ut_MTapAndHoldRecognizer::cleanup()
{
    delete recognizer;
}

void Ut_MTapAndHoldRecognizer::testCreateGesture()
{
    tapAndHoldGesture = static_cast<MTapAndHoldGesture*>(recognizer->create(view));
}

void Ut_MTapAndHoldRecognizer::testRecognize()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    QTimerEvent fakeTimerEvent(tapAndHoldGesture->timerId);
    currentState = recognizer->recognize(tapAndHoldGesture, tapAndHoldGesture, &fakeTimerEvent);
    QCOMPARE( currentState, QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint );

    delete pressEvent;
}

void Ut_MTapAndHoldRecognizer::testFastTap()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    //Setting timerId as would happen in real life scenario
    tapAndHoldGesture->timerId = 1;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, releaseEvent);
    QCOMPARE( currentState, QGestureRecognizer::CancelGesture);

    delete pressEvent;
    delete releaseEvent;
}

void Ut_MTapAndHoldRecognizer::testMovePointerInsideThreshold()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *moveEvent = new QMouseEvent(QEvent::MouseMove, QPoint(3,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    currentGestureState = Qt::GestureStarted;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, moveEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    QTimerEvent fakeTimerEvent(tapAndHoldGesture->timerId);
    currentState = recognizer->recognize(tapAndHoldGesture, tapAndHoldGesture, &fakeTimerEvent);
    QCOMPARE( currentState, QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint );

    delete pressEvent;
    delete moveEvent;
}

void Ut_MTapAndHoldRecognizer::testMovePointerBeyondThreshold()
{
    QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QMouseEvent *moveEvent = new QMouseEvent(QEvent::MouseMove, QPoint(50,0), Qt::LeftButton, Qt::LeftButton, 0);

    QGestureRecognizer::Result currentState;
    currentState = recognizer->recognize(tapAndHoldGesture, 0, pressEvent);
    QCOMPARE( currentState, QGestureRecognizer::TriggerGesture);

    currentGestureState = Qt::GestureStarted;

    currentState = recognizer->recognize(tapAndHoldGesture, 0, moveEvent);
    QCOMPARE( currentState, QGestureRecognizer::CancelGesture);

    delete pressEvent;
    delete moveEvent;
}

void Ut_MTapAndHoldRecognizer::testUsingStyleTimeout()
{
    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);
    Q_UNUSED(currentState);

    // Verify that timeout from style is used when no timeout is set
    QCOMPARE(startTimerInterval, MTapAndHoldStyleTimeout);
}

void Ut_MTapAndHoldRecognizer::testSetTimeout()
{
    QTapAndHoldGesture::setTimeout(MTapAndHoldSetTimeout);

    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);
    Q_UNUSED(currentState);

    // Verify that timeout that was set is used
    QCOMPARE(startTimerInterval, MTapAndHoldSetTimeout);
}

void Ut_MTapAndHoldRecognizer::testResetTimeout()
{
    QTapAndHoldGesture::setTimeout(MTapAndHoldSetTimeout);

    // Reset timeout
    QTapAndHoldGesture::setTimeout(-1);

    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::LeftButton, 0);
    QGestureRecognizer::Result currentState = recognizer->recognize(tapAndHoldGesture, 0, &pressEvent);
    Q_UNUSED(currentState);

    // Verify that as timeout was resetted then timeout from style is used
    QCOMPARE(startTimerInterval, MTapAndHoldStyleTimeout);
}

QTEST_APPLESS_MAIN(Ut_MTapAndHoldRecognizer)

<|endoftext|>


<commit_before>// Time:  O(nlogw)
// Space: O(w)

class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
        multiset<int, less<int>> min_bst;
        multiset<int, greater<int>> max_bst;

        vector<double> result;
        for (int i = 0; i < nums.size(); ++i) {
            if (i >= k) {
                if (max_bst.find(nums[i - k]) != max_bst.cend()) {
                    max_bst.erase(max_bst.find(nums[i - k]));
                } else {
                    min_bst.erase(min_bst.find(nums[i - k]));
                }
            }

            if (max_bst.empty() || nums[i] > *max_bst.cbegin()) {
                min_bst.emplace(nums[i]);
                if (min_bst.size() > max_bst.size() + 1) {
                    max_bst.emplace(*min_bst.cbegin());
                    min_bst.erase(min_bst.cbegin());
                }
            } else {
                max_bst.emplace(nums[i]);
                if (max_bst.size() > min_bst.size()) {
                    min_bst.emplace(*max_bst.cbegin());
                    max_bst.erase(max_bst.cbegin());
                }
            }

            if (i >= k - 1) {
                result.emplace_back(min_bst.size() == max_bst.size() ?
                                 *max_bst.cbegin() / 2.0 + *min_bst.cbegin() / 2.0 : *min_bst.cbegin());
            }
        }

        return result;
    }
};
<commit_msg>Update sliding-window-median.cpp<commit_after>// Time:  O(nlogk)
// Space: O(k)

class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
        multiset<int, less<int>> min_bst;
        multiset<int, greater<int>> max_bst;

        vector<double> result;
        for (int i = 0; i < nums.size(); ++i) {
            if (i >= k) {
                if (max_bst.find(nums[i - k]) != max_bst.cend()) {
                    max_bst.erase(max_bst.find(nums[i - k]));
                } else {
                    min_bst.erase(min_bst.find(nums[i - k]));
                }
            }

            if (max_bst.empty() || nums[i] > *max_bst.cbegin()) {
                min_bst.emplace(nums[i]);
                if (min_bst.size() > max_bst.size() + 1) {
                    max_bst.emplace(*min_bst.cbegin());
                    min_bst.erase(min_bst.cbegin());
                }
            } else {
                max_bst.emplace(nums[i]);
                if (max_bst.size() > min_bst.size()) {
                    min_bst.emplace(*max_bst.cbegin());
                    max_bst.erase(max_bst.cbegin());
                }
            }

            if (i >= k - 1) {
                result.emplace_back(min_bst.size() == max_bst.size() ?
                                 *max_bst.cbegin() / 2.0 + *min_bst.cbegin() / 2.0 : *min_bst.cbegin());
            }
        }

        return result;
    }
};
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2016, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once

#include <Param.hpp>
#include <common/dispatch.hpp>
#include <common/kernel_cache.hpp>
#include <debug_opencl.hpp>
#include <kernel/config.hpp>
#include <kernel/reduce.hpp>
#include <kernel/scan_dim.hpp>
#include <kernel/scan_first.hpp>
#include <kernel_headers/csrmm.hpp>
#include <traits.hpp>
#include <af/opencl.h>

#include <string>
#include <vector>

namespace opencl {
namespace kernel {
template<typename T>
void csrmm_nt(Param out, const Param &values, const Param &rowIdx,
              const Param &colIdx, const Param &rhs, const T alpha,
              const T beta) {
    constexpr int MAX_CSRMM_GROUPS = 4096;
    // Using greedy indexing is causing performance issues on many platforms
    // FIXME: Figure out why
    constexpr bool use_greedy = false;

    const bool use_alpha = (alpha != scalar<T>(1.0));
    const bool use_beta  = (beta != scalar<T>(0.0));

    std::vector<TemplateArg> targs = {
        TemplateTypename<T>(),
        TemplateArg(use_alpha),
        TemplateArg(use_beta),
        TemplateArg(use_greedy),
    };
    std::vector<std::string> options = {
        DefineKeyValue(T, dtype_traits<T>::getName()),
        DefineKeyValue(USE_ALPHA, use_alpha),
        DefineKeyValue(USE_BETA, use_beta),
        DefineKeyValue(USE_GREEDY, use_greedy),
        DefineValue(THREADS_PER_GROUP),
        DefineKeyValue(IS_CPLX, (af::iscplx<T>() ? 1 : 0)),
    };
    options.emplace_back(getTypeBuildDefinition<T>());

    // FIXME: Switch to perf (thread vs block) baesd kernel
    auto csrmm_nt_func =
        common::getKernel("csrmm_nt", {csrmm_cl_src}, targs, options);

    cl::NDRange local(THREADS_PER_GROUP, 1);
    int M = rowIdx.info.dims[0] - 1;
    int N = rhs.info.dims[0];

    int groups_x = divup(N, local[0]);
    int groups_y = divup(M, REPEAT);
    groups_y     = std::min(groups_y, MAX_CSRMM_GROUPS);
    cl::NDRange global(local[0] * groups_x, local[1] * groups_y);

    std::vector<int> count(groups_x);
    cl::Buffer *counter = bufferAlloc(count.size() * sizeof(int));
    getQueue().enqueueWriteBuffer(
        *counter, CL_TRUE, 0, count.size() * sizeof(int), (void *)count.data());

    csrmm_nt_func(cl::EnqueueArgs(getQueue(), global, local), *out.data,
                  *values.data, *rowIdx.data, *colIdx.data, M, N, *rhs.data,
                  rhs.info, alpha, beta, *counter);
    bufferFree(counter);
}
}  // namespace kernel
}  // namespace opencl
<commit_msg>Use CL fill buffer instead of host allocation in csrmm kernel<commit_after>/*******************************************************
 * Copyright (c) 2016, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once

#include <Param.hpp>
#include <common/dispatch.hpp>
#include <common/kernel_cache.hpp>
#include <debug_opencl.hpp>
#include <kernel/config.hpp>
#include <kernel/reduce.hpp>
#include <kernel/scan_dim.hpp>
#include <kernel/scan_first.hpp>
#include <kernel_headers/csrmm.hpp>
#include <traits.hpp>
#include <af/opencl.h>

#include <string>
#include <vector>

namespace opencl {
namespace kernel {
template<typename T>
void csrmm_nt(Param out, const Param &values, const Param &rowIdx,
              const Param &colIdx, const Param &rhs, const T alpha,
              const T beta) {
    constexpr int MAX_CSRMM_GROUPS = 4096;
    // Using greedy indexing is causing performance issues on many platforms
    // FIXME: Figure out why
    constexpr bool use_greedy = false;

    const bool use_alpha = (alpha != scalar<T>(1.0));
    const bool use_beta  = (beta != scalar<T>(0.0));

    std::vector<TemplateArg> targs = {
        TemplateTypename<T>(),
        TemplateArg(use_alpha),
        TemplateArg(use_beta),
        TemplateArg(use_greedy),
    };
    std::vector<std::string> options = {
        DefineKeyValue(T, dtype_traits<T>::getName()),
        DefineKeyValue(USE_ALPHA, use_alpha),
        DefineKeyValue(USE_BETA, use_beta),
        DefineKeyValue(USE_GREEDY, use_greedy),
        DefineValue(THREADS_PER_GROUP),
        DefineKeyValue(IS_CPLX, (af::iscplx<T>() ? 1 : 0)),
    };
    options.emplace_back(getTypeBuildDefinition<T>());

    // FIXME: Switch to perf (thread vs block) baesd kernel
    auto csrmm_nt_func =
        common::getKernel("csrmm_nt", {csrmm_cl_src}, targs, options);

    cl::NDRange local(THREADS_PER_GROUP, 1);
    int M = rowIdx.info.dims[0] - 1;
    int N = rhs.info.dims[0];

    int groups_x = divup(N, local[0]);
    int groups_y = divup(M, REPEAT);
    groups_y     = std::min(groups_y, MAX_CSRMM_GROUPS);
    cl::NDRange global(local[0] * groups_x, local[1] * groups_y);

    cl::Buffer *counter = bufferAlloc(groups_x * sizeof(int));
    getQueue().enqueueFillBuffer(*counter, 0, 0, groups_x * sizeof(int));

    csrmm_nt_func(cl::EnqueueArgs(getQueue(), global, local), *out.data,
                  *values.data, *rowIdx.data, *colIdx.data, M, N, *rhs.data,
                  rhs.info, alpha, beta, *counter);
    bufferFree(counter);
}
}  // namespace kernel
}  // namespace opencl
<|endoftext|>


<commit_before>// Copyright 2006-2008 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/logging.h"

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

#include <iomanip>

#if defined(OS_POSIX)
#include <paths.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "base/posix/safe_strerror.h"
#endif  // OS_POSIX

#if defined(OS_MACOSX)
#include <AvailabilityMacros.h>
#include <CoreFoundation/CoreFoundation.h>
#include <pthread.h>
#if !defined(MAC_OS_X_VERSION_10_12) || \
    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
#include <asl.h>
#else
#include <os/log.h>
#endif
#elif defined(OS_LINUX)
#include <sys/syscall.h>
#include <sys/types.h>
#elif defined(OS_WIN)
#include <windows.h>
#endif

#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"

namespace logging {

namespace {

const char* const log_severity_names[] = {
  "INFO",
  "WARNING",
  "ERROR",
  "ERROR_REPORT",
  "FATAL"
};

LogMessageHandlerFunction g_log_message_handler = nullptr;

}  // namespace

void SetLogMessageHandler(LogMessageHandlerFunction log_message_handler) {
  g_log_message_handler = log_message_handler;
}

LogMessageHandlerFunction GetLogMessageHandler() {
  return g_log_message_handler;
}

#if defined(OS_WIN)
std::string SystemErrorCodeToString(unsigned long error_code) {
  wchar_t msgbuf[256];
  DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
                FORMAT_MESSAGE_MAX_WIDTH_MASK;
  DWORD len = FormatMessage(
      flags, nullptr, error_code, 0, msgbuf, arraysize(msgbuf), nullptr);
  if (len) {
    // Most system messages end in a period and a space. Remove the space if
    // it’s there, because the following StringPrintf() includes one.
    if (len >= 1 && msgbuf[len - 1] == ' ') {
      msgbuf[len - 1] = '\0';
    }
    return base::StringPrintf("%s (%u)",
                              base::UTF16ToUTF8(msgbuf).c_str(), error_code);
  }
  return base::StringPrintf("Error %u while retrieving error %u",
                            GetLastError(),
                            error_code);
}
#endif  // OS_WIN

LogMessage::LogMessage(const char* function,
                       const char* file_path,
                       int line,
                       LogSeverity severity)
    : stream_(),
      file_path_(file_path),
      message_start_(0),
      line_(line),
      severity_(severity) {
  Init(function);
}

LogMessage::LogMessage(const char* function,
                       const char* file_path,
                       int line,
                       std::string* result)
    : stream_(),
      file_path_(file_path),
      message_start_(0),
      line_(line),
      severity_(LOG_FATAL) {
  Init(function);
  stream_ << "Check failed: " << *result << ". ";
  delete result;
}

LogMessage::~LogMessage() {
  stream_ << std::endl;
  std::string str_newline(stream_.str());

  if (g_log_message_handler &&
      g_log_message_handler(
          severity_, file_path_, line_, message_start_, str_newline)) {
    return;
  }

  fprintf(stderr, "%s", str_newline.c_str());
  fflush(stderr);

#if defined(OS_MACOSX)
  const bool log_to_system = []() {
    struct stat stderr_stat;
    if (fstat(fileno(stderr), &stderr_stat) == -1) {
      return true;
    }
    if (!S_ISCHR(stderr_stat.st_mode)) {
      return false;
    }

    struct stat dev_null_stat;
    if (stat(_PATH_DEVNULL, &dev_null_stat) == -1) {
      return true;
    }

    return !S_ISCHR(dev_null_stat.st_mode) ||
           stderr_stat.st_rdev == dev_null_stat.st_rdev;
  }();

  if (log_to_system) {
    CFBundleRef main_bundle = CFBundleGetMainBundle();
    CFStringRef main_bundle_id_cf =
        main_bundle ? CFBundleGetIdentifier(main_bundle) : nullptr;

    std::string main_bundle_id_buf;
    const char* main_bundle_id = nullptr;

    if (main_bundle_id_cf) {
      main_bundle_id =
          CFStringGetCStringPtr(main_bundle_id_cf, kCFStringEncodingUTF8);
      if (!main_bundle_id) {
        // 1024 is from 10.10.5 CF-1153.18/CFBundle.c __CFBundleMainID__ (at
        // the point of use, not declaration).
        main_bundle_id_buf.resize(1024);
        if (!CFStringGetCString(main_bundle_id_cf,
                                &main_bundle_id_buf[0],
                                main_bundle_id_buf.size(),
                                kCFStringEncodingUTF8)) {
          main_bundle_id_buf.clear();
        } else {
          main_bundle_id = &main_bundle_id_buf[0];
        }
      }
    }

#if !defined(MAC_OS_X_VERSION_10_12) || \
    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
    // Use ASL when this might run on pre-10.12 systems. Unified Logging
    // (os_log) was introduced in 10.12.

    const class ASLClient {
     public:
      explicit ASLClient(const char* asl_facility)
          : client_(asl_open(nullptr, asl_facility, ASL_OPT_NO_DELAY)) {}
      ~ASLClient() { asl_close(client_); }

      aslclient get() const { return client_; }

     private:
      aslclient client_;
      DISALLOW_COPY_AND_ASSIGN(ASLClient);
    } asl_client(main_bundle_id ? main_bundle_id : "com.apple.console");

    const class ASLMessage {
     public:
      ASLMessage() : message_(asl_new(ASL_TYPE_MSG)) {}
      ~ASLMessage() { asl_free(message_); }

      aslmsg get() const { return message_; }

     private:
      aslmsg message_;
      DISALLOW_COPY_AND_ASSIGN(ASLMessage);
    } asl_message;

    // By default, messages are only readable by the admin group. Explicitly
    // make them readable by the user generating the messages.
    char euid_string[12];
    snprintf(euid_string, arraysize(euid_string), "%d", geteuid());
    asl_set(asl_message.get(), ASL_KEY_READ_UID, euid_string);

    // Map Chrome log severities to ASL log levels.
    const char* const asl_level_string = [](LogSeverity severity) {
#define ASL_LEVEL_STR(level) ASL_LEVEL_STR_X(level)
#define ASL_LEVEL_STR_X(level) #level
        switch (severity) {
          case LOG_INFO:
            return ASL_LEVEL_STR(ASL_LEVEL_INFO);
          case LOG_WARNING:
            return ASL_LEVEL_STR(ASL_LEVEL_WARNING);
          case LOG_ERROR:
            return ASL_LEVEL_STR(ASL_LEVEL_ERR);
          case LOG_FATAL:
            return ASL_LEVEL_STR(ASL_LEVEL_CRIT);
          default:
            return severity < 0 ? ASL_LEVEL_STR(ASL_LEVEL_DEBUG)
                                : ASL_LEVEL_STR(ASL_LEVEL_NOTICE);
        }
#undef ASL_LEVEL_STR
#undef ASL_LEVEL_STR_X
    }(severity_);
    asl_set(asl_message.get(), ASL_KEY_LEVEL, asl_level_string);

    asl_set(asl_message.get(), ASL_KEY_MSG, str_newline.c_str());

    asl_send(asl_client.get(), asl_message.get());
#else
    // Use Unified Logging (os_log) when this will only run on 10.12 and later.
    // ASL is deprecated in 10.12.

    const class OSLog {
     public:
      explicit OSLog(const char* subsystem)
          : os_log_(subsystem ? os_log_create(subsystem, "chromium_logging")
                              : OS_LOG_DEFAULT) {}
      ~OSLog() {
        if (os_log_ != OS_LOG_DEFAULT) {
          os_release(os_log_);
        }
      }

      os_log_t get() const { return os_log_; }

     private:
      os_log_t os_log_;
      DISALLOW_COPY_AND_ASSIGN(OSLog);
    } log(main_bundle_id);

    const os_log_type_t os_log_type = [](LogSeverity severity) {
      switch (severity) {
        case LOG_INFO:
          return OS_LOG_TYPE_INFO;
        case LOG_WARNING:
          return OS_LOG_TYPE_DEFAULT;
        case LOG_ERROR:
          return OS_LOG_TYPE_ERROR;
        case LOG_FATAL:
          return OS_LOG_TYPE_FAULT;
        default:
          return severity < 0 ? OS_LOG_TYPE_DEBUG : OS_LOG_TYPE_DEFAULT;
      }
    }(severity_);

    os_log_with_type(log.get(), os_log_type, "%{public}s", str_newline.c_str());
#endif
  }
#elif defined(OS_WIN)
  OutputDebugString(base::UTF8ToUTF16(str_newline).c_str());
#endif  // OS_MACOSX

  if (severity_ == LOG_FATAL) {
#if defined(COMPILER_MSVC)
    __debugbreak();
    __ud2();
#elif defined(ARCH_CPU_X86_FAMILY)
    asm("int3; ud2;");
#elif defined(ARCH_CPU_ARMEL)
    asm("bkpt #0; udf #0;");
#elif defined(ARCH_CPU_ARM64)
    asm("brk #0; hlt #0;");
#else
    __builtin_trap();
#endif
  }
}

void LogMessage::Init(const char* function) {
  std::string file_name(file_path_);
#if defined(OS_WIN)
  size_t last_slash = file_name.find_last_of("\\/");
#else
  size_t last_slash = file_name.find_last_of('/');
#endif
  if (last_slash != std::string::npos) {
    file_name.assign(file_name.substr(last_slash + 1));
  }

#if defined(OS_POSIX)
  pid_t pid = getpid();
#elif defined(OS_WIN)
  DWORD pid = GetCurrentProcessId();
#endif

#if defined(OS_MACOSX)
  uint64_t thread;
  pthread_threadid_np(pthread_self(), &thread);
#elif defined(OS_ANDROID)
  pid_t thread = gettid();
#elif defined(OS_LINUX)
  pid_t thread = syscall(__NR_gettid);
#elif defined(OS_WIN)
  DWORD thread = GetCurrentThreadId();
#endif

  stream_ << '['
          << pid
          << ':'
          << thread
          << ':'
          << std::setfill('0');

#if defined(OS_POSIX)
  timeval tv;
  gettimeofday(&tv, nullptr);
  tm local_time;
  localtime_r(&tv.tv_sec, &local_time);
  stream_ << std::setw(4) << local_time.tm_year + 1900
          << std::setw(2) << local_time.tm_mon + 1
          << std::setw(2) << local_time.tm_mday
          << ','
          << std::setw(2) << local_time.tm_hour
          << std::setw(2) << local_time.tm_min
          << std::setw(2) << local_time.tm_sec
          << '.'
          << std::setw(6) << tv.tv_usec;
#elif defined(OS_WIN)
  SYSTEMTIME local_time;
  GetLocalTime(&local_time);
  stream_ << std::setw(4) << local_time.wYear
          << std::setw(2) << local_time.wMonth
          << std::setw(2) << local_time.wDay
          << ','
          << std::setw(2) << local_time.wHour
          << std::setw(2) << local_time.wMinute
          << std::setw(2) << local_time.wSecond
          << '.'
          << std::setw(3) << local_time.wMilliseconds;
#endif

  stream_ << ':';

  if (severity_ >= 0) {
    stream_ << log_severity_names[severity_];
  } else {
    stream_ << "VERBOSE" << -severity_;
  }

  stream_ << ' '
          << file_name
          << ':'
          << line_
          << "] ";

  message_start_ = stream_.str().size();
}

#if defined(OS_WIN)

unsigned long GetLastSystemErrorCode() {
  return GetLastError();
}

Win32ErrorLogMessage::Win32ErrorLogMessage(const char* function,
                                           const char* file_path,
                                           int line,
                                           LogSeverity severity,
                                           unsigned long err)
    : LogMessage(function, file_path, line, severity), err_(err) {
}

Win32ErrorLogMessage::~Win32ErrorLogMessage() {
  stream() << ": " << SystemErrorCodeToString(err_);
}

#elif defined(OS_POSIX)

ErrnoLogMessage::ErrnoLogMessage(const char* function,
                                 const char* file_path,
                                 int line,
                                 LogSeverity severity,
                                 int err)
    : LogMessage(function, file_path, line, severity),
      err_(err) {
}

ErrnoLogMessage::~ErrnoLogMessage() {
  stream() << ": "
           << base::safe_strerror(err_)
           << " ("
           << err_
           << ")";
}

#endif  // OS_POSIX

}  // namespace logging
<commit_msg>win: MSVS 2017 (15)/C++ 14.1/C 19.10 compatibility<commit_after>// Copyright 2006-2008 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/logging.h"

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

#include <iomanip>

#if defined(OS_POSIX)
#include <paths.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "base/posix/safe_strerror.h"
#endif  // OS_POSIX

#if defined(OS_MACOSX)
#include <AvailabilityMacros.h>
#include <CoreFoundation/CoreFoundation.h>
#include <pthread.h>
#if !defined(MAC_OS_X_VERSION_10_12) || \
    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
#include <asl.h>
#else
#include <os/log.h>
#endif
#elif defined(OS_LINUX)
#include <sys/syscall.h>
#include <sys/types.h>
#elif defined(OS_WIN)
#include <intrin.h>
#include <windows.h>
#endif

#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"

namespace logging {

namespace {

const char* const log_severity_names[] = {
  "INFO",
  "WARNING",
  "ERROR",
  "ERROR_REPORT",
  "FATAL"
};

LogMessageHandlerFunction g_log_message_handler = nullptr;

}  // namespace

void SetLogMessageHandler(LogMessageHandlerFunction log_message_handler) {
  g_log_message_handler = log_message_handler;
}

LogMessageHandlerFunction GetLogMessageHandler() {
  return g_log_message_handler;
}

#if defined(OS_WIN)
std::string SystemErrorCodeToString(unsigned long error_code) {
  wchar_t msgbuf[256];
  DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
                FORMAT_MESSAGE_MAX_WIDTH_MASK;
  DWORD len = FormatMessage(
      flags, nullptr, error_code, 0, msgbuf, arraysize(msgbuf), nullptr);
  if (len) {
    // Most system messages end in a period and a space. Remove the space if
    // it’s there, because the following StringPrintf() includes one.
    if (len >= 1 && msgbuf[len - 1] == ' ') {
      msgbuf[len - 1] = '\0';
    }
    return base::StringPrintf("%s (%u)",
                              base::UTF16ToUTF8(msgbuf).c_str(), error_code);
  }
  return base::StringPrintf("Error %u while retrieving error %u",
                            GetLastError(),
                            error_code);
}
#endif  // OS_WIN

LogMessage::LogMessage(const char* function,
                       const char* file_path,
                       int line,
                       LogSeverity severity)
    : stream_(),
      file_path_(file_path),
      message_start_(0),
      line_(line),
      severity_(severity) {
  Init(function);
}

LogMessage::LogMessage(const char* function,
                       const char* file_path,
                       int line,
                       std::string* result)
    : stream_(),
      file_path_(file_path),
      message_start_(0),
      line_(line),
      severity_(LOG_FATAL) {
  Init(function);
  stream_ << "Check failed: " << *result << ". ";
  delete result;
}

LogMessage::~LogMessage() {
  stream_ << std::endl;
  std::string str_newline(stream_.str());

  if (g_log_message_handler &&
      g_log_message_handler(
          severity_, file_path_, line_, message_start_, str_newline)) {
    return;
  }

  fprintf(stderr, "%s", str_newline.c_str());
  fflush(stderr);

#if defined(OS_MACOSX)
  const bool log_to_system = []() {
    struct stat stderr_stat;
    if (fstat(fileno(stderr), &stderr_stat) == -1) {
      return true;
    }
    if (!S_ISCHR(stderr_stat.st_mode)) {
      return false;
    }

    struct stat dev_null_stat;
    if (stat(_PATH_DEVNULL, &dev_null_stat) == -1) {
      return true;
    }

    return !S_ISCHR(dev_null_stat.st_mode) ||
           stderr_stat.st_rdev == dev_null_stat.st_rdev;
  }();

  if (log_to_system) {
    CFBundleRef main_bundle = CFBundleGetMainBundle();
    CFStringRef main_bundle_id_cf =
        main_bundle ? CFBundleGetIdentifier(main_bundle) : nullptr;

    std::string main_bundle_id_buf;
    const char* main_bundle_id = nullptr;

    if (main_bundle_id_cf) {
      main_bundle_id =
          CFStringGetCStringPtr(main_bundle_id_cf, kCFStringEncodingUTF8);
      if (!main_bundle_id) {
        // 1024 is from 10.10.5 CF-1153.18/CFBundle.c __CFBundleMainID__ (at
        // the point of use, not declaration).
        main_bundle_id_buf.resize(1024);
        if (!CFStringGetCString(main_bundle_id_cf,
                                &main_bundle_id_buf[0],
                                main_bundle_id_buf.size(),
                                kCFStringEncodingUTF8)) {
          main_bundle_id_buf.clear();
        } else {
          main_bundle_id = &main_bundle_id_buf[0];
        }
      }
    }

#if !defined(MAC_OS_X_VERSION_10_12) || \
    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
    // Use ASL when this might run on pre-10.12 systems. Unified Logging
    // (os_log) was introduced in 10.12.

    const class ASLClient {
     public:
      explicit ASLClient(const char* asl_facility)
          : client_(asl_open(nullptr, asl_facility, ASL_OPT_NO_DELAY)) {}
      ~ASLClient() { asl_close(client_); }

      aslclient get() const { return client_; }

     private:
      aslclient client_;
      DISALLOW_COPY_AND_ASSIGN(ASLClient);
    } asl_client(main_bundle_id ? main_bundle_id : "com.apple.console");

    const class ASLMessage {
     public:
      ASLMessage() : message_(asl_new(ASL_TYPE_MSG)) {}
      ~ASLMessage() { asl_free(message_); }

      aslmsg get() const { return message_; }

     private:
      aslmsg message_;
      DISALLOW_COPY_AND_ASSIGN(ASLMessage);
    } asl_message;

    // By default, messages are only readable by the admin group. Explicitly
    // make them readable by the user generating the messages.
    char euid_string[12];
    snprintf(euid_string, arraysize(euid_string), "%d", geteuid());
    asl_set(asl_message.get(), ASL_KEY_READ_UID, euid_string);

    // Map Chrome log severities to ASL log levels.
    const char* const asl_level_string = [](LogSeverity severity) {
#define ASL_LEVEL_STR(level) ASL_LEVEL_STR_X(level)
#define ASL_LEVEL_STR_X(level) #level
        switch (severity) {
          case LOG_INFO:
            return ASL_LEVEL_STR(ASL_LEVEL_INFO);
          case LOG_WARNING:
            return ASL_LEVEL_STR(ASL_LEVEL_WARNING);
          case LOG_ERROR:
            return ASL_LEVEL_STR(ASL_LEVEL_ERR);
          case LOG_FATAL:
            return ASL_LEVEL_STR(ASL_LEVEL_CRIT);
          default:
            return severity < 0 ? ASL_LEVEL_STR(ASL_LEVEL_DEBUG)
                                : ASL_LEVEL_STR(ASL_LEVEL_NOTICE);
        }
#undef ASL_LEVEL_STR
#undef ASL_LEVEL_STR_X
    }(severity_);
    asl_set(asl_message.get(), ASL_KEY_LEVEL, asl_level_string);

    asl_set(asl_message.get(), ASL_KEY_MSG, str_newline.c_str());

    asl_send(asl_client.get(), asl_message.get());
#else
    // Use Unified Logging (os_log) when this will only run on 10.12 and later.
    // ASL is deprecated in 10.12.

    const class OSLog {
     public:
      explicit OSLog(const char* subsystem)
          : os_log_(subsystem ? os_log_create(subsystem, "chromium_logging")
                              : OS_LOG_DEFAULT) {}
      ~OSLog() {
        if (os_log_ != OS_LOG_DEFAULT) {
          os_release(os_log_);
        }
      }

      os_log_t get() const { return os_log_; }

     private:
      os_log_t os_log_;
      DISALLOW_COPY_AND_ASSIGN(OSLog);
    } log(main_bundle_id);

    const os_log_type_t os_log_type = [](LogSeverity severity) {
      switch (severity) {
        case LOG_INFO:
          return OS_LOG_TYPE_INFO;
        case LOG_WARNING:
          return OS_LOG_TYPE_DEFAULT;
        case LOG_ERROR:
          return OS_LOG_TYPE_ERROR;
        case LOG_FATAL:
          return OS_LOG_TYPE_FAULT;
        default:
          return severity < 0 ? OS_LOG_TYPE_DEBUG : OS_LOG_TYPE_DEFAULT;
      }
    }(severity_);

    os_log_with_type(log.get(), os_log_type, "%{public}s", str_newline.c_str());
#endif
  }
#elif defined(OS_WIN)
  OutputDebugString(base::UTF8ToUTF16(str_newline).c_str());
#endif  // OS_MACOSX

  if (severity_ == LOG_FATAL) {
#if defined(COMPILER_MSVC)
    __debugbreak();
    __ud2();
#elif defined(ARCH_CPU_X86_FAMILY)
    asm("int3; ud2;");
#elif defined(ARCH_CPU_ARMEL)
    asm("bkpt #0; udf #0;");
#elif defined(ARCH_CPU_ARM64)
    asm("brk #0; hlt #0;");
#else
    __builtin_trap();
#endif
  }
}

void LogMessage::Init(const char* function) {
  std::string file_name(file_path_);
#if defined(OS_WIN)
  size_t last_slash = file_name.find_last_of("\\/");
#else
  size_t last_slash = file_name.find_last_of('/');
#endif
  if (last_slash != std::string::npos) {
    file_name.assign(file_name.substr(last_slash + 1));
  }

#if defined(OS_POSIX)
  pid_t pid = getpid();
#elif defined(OS_WIN)
  DWORD pid = GetCurrentProcessId();
#endif

#if defined(OS_MACOSX)
  uint64_t thread;
  pthread_threadid_np(pthread_self(), &thread);
#elif defined(OS_ANDROID)
  pid_t thread = gettid();
#elif defined(OS_LINUX)
  pid_t thread = syscall(__NR_gettid);
#elif defined(OS_WIN)
  DWORD thread = GetCurrentThreadId();
#endif

  stream_ << '['
          << pid
          << ':'
          << thread
          << ':'
          << std::setfill('0');

#if defined(OS_POSIX)
  timeval tv;
  gettimeofday(&tv, nullptr);
  tm local_time;
  localtime_r(&tv.tv_sec, &local_time);
  stream_ << std::setw(4) << local_time.tm_year + 1900
          << std::setw(2) << local_time.tm_mon + 1
          << std::setw(2) << local_time.tm_mday
          << ','
          << std::setw(2) << local_time.tm_hour
          << std::setw(2) << local_time.tm_min
          << std::setw(2) << local_time.tm_sec
          << '.'
          << std::setw(6) << tv.tv_usec;
#elif defined(OS_WIN)
  SYSTEMTIME local_time;
  GetLocalTime(&local_time);
  stream_ << std::setw(4) << local_time.wYear
          << std::setw(2) << local_time.wMonth
          << std::setw(2) << local_time.wDay
          << ','
          << std::setw(2) << local_time.wHour
          << std::setw(2) << local_time.wMinute
          << std::setw(2) << local_time.wSecond
          << '.'
          << std::setw(3) << local_time.wMilliseconds;
#endif

  stream_ << ':';

  if (severity_ >= 0) {
    stream_ << log_severity_names[severity_];
  } else {
    stream_ << "VERBOSE" << -severity_;
  }

  stream_ << ' '
          << file_name
          << ':'
          << line_
          << "] ";

  message_start_ = stream_.str().size();
}

#if defined(OS_WIN)

unsigned long GetLastSystemErrorCode() {
  return GetLastError();
}

Win32ErrorLogMessage::Win32ErrorLogMessage(const char* function,
                                           const char* file_path,
                                           int line,
                                           LogSeverity severity,
                                           unsigned long err)
    : LogMessage(function, file_path, line, severity), err_(err) {
}

Win32ErrorLogMessage::~Win32ErrorLogMessage() {
  stream() << ": " << SystemErrorCodeToString(err_);
}

#elif defined(OS_POSIX)

ErrnoLogMessage::ErrnoLogMessage(const char* function,
                                 const char* file_path,
                                 int line,
                                 LogSeverity severity,
                                 int err)
    : LogMessage(function, file_path, line, severity),
      err_(err) {
}

ErrnoLogMessage::~ErrnoLogMessage() {
  stream() << ": "
           << base::safe_strerror(err_)
           << " ("
           << err_
           << ")";
}

#endif  // OS_POSIX

}  // namespace logging
<|endoftext|>


<commit_before>/*!
 * \file hyo_utilities_tests.cpp
 * \author Robert 'Bob' Caddy (rvc@pitt.edu), Helena Richie (helenarichie@pitt.edu)
 * \brief Tests for the contents of hydro_utilities.h and hydro_utilities.cpp
 *
 */

// STL Includes
#include <vector>
#include <string>
#include <iostream>

// External Includes
#include <gtest/gtest.h>    // Include GoogleTest and related libraries/headers

// Local Includes
#include "../utils/testing_utilities.h"
#include "../utils/hydro_utilities.h"
#include "../global/global.h"

// =============================================================================
// Local helper functions

/*!
* INDEX OF VARIABLES
* p : pressure
* vx, vy, vz : x, y, and z velocity
* d : density
* E : energy
* T : temperature
* px, py, pz : x, y, and z momentum
* n : number density
*/

namespace
{
    struct TestParams
    {
        double gamma = 5./3.;
        std::vector<double> d {8.4087201154e-100, 1.6756968986e2, 5.4882403847e100};
        std::vector<double> vx {7.0378624601e-100, 7.0829278656e2, 1.8800514112e100};
        std::vector<double> vy {7.3583469014e-100, 5.9283073464e2, 5.2725717864e100};
        std::vector<double> vz {1.7182972216e-100, 8.8417748226e2, 1.5855352639e100};
        std::vector<double> px {8.2340416681e-100, 8.1019429453e2, 5.5062596954e100};
        std::vector<double> py {4.9924582299e-100, 7.1254780684e2, 6.5939640992e100};
        std::vector<double> pz {3.6703192739e-100, 7.5676716066e2, 7.2115881803e100};
        std::vector<double> E {3.0342082433e-100, 7.6976906577e2, 1.9487120853e100};
        std::vector<double> p {2.2244082909e-100, 8.6772951021e2, 6.7261085663e100};
        std::vector<std::string> names{"Small number case", "Medium number case", "Large number case"};
    };
}

TEST(tHYDROSYSTEMHydroUtilsCalcPressureConserved, CorrectInputExpectCorrectOutput) {
    TestParams parameters;
    std::vector<double> fiducial_ps {3.3366124363499995e-100, 9.9999999999999995e-21, 2.4282508238146436e+100};

    for (size_t i = 0; i < parameters.names.size(); i++)
    {
        Real test_ps = hydro_utilities::Calc_Pressure_Conserved(parameters.E.at(i), parameters.d.at(i), parameters.px.at(i), parameters.py.at(i), parameters.pz.at(i), parameters.gamma);

        testingUtilities::checkResults(fiducial_ps.at(i), test_ps, parameters.names.at(i));
    }
}

TEST(tHYDROSYSTEMHydroUtilsCalcPressurePrimitive, CorrectInputExpectCorrectOutput) {
    TestParams parameters;
    std::vector<double> fiducial_pressures{3.3366124363499995e-100, 9.9999999999999995e-21, 2.4282508238146436e+100};

    for (size_t i = 0; i < parameters.names.size(); i++)
    {
        Real test_p = hydro_utilities::Calc_Pressure_Conserved(parameters.p.at(i), parameters.d.at(i), parameters.vx.at(i), parameters.vy.at(i), parameters.vz.at(i), parameters.gamma);

        testingUtilities::checkResults(fiducial_pressures.at(i), test_p, parameters.names.at(i));
    }
}<commit_msg>add hydro utility function testing<commit_after>/*!
 * \file hyo_utilities_tests.cpp
 * \author Robert 'Bob' Caddy (rvc@pitt.edu), Helena Richie (helenarichie@pitt.edu)
 * \brief Tests for the contents of hydro_utilities.h and hydro_utilities.cpp
 *
 */

// STL Includes
#include <vector>
#include <string>
#include <iostream>

// External Includes
#include <gtest/gtest.h>    // Include GoogleTest and related libraries/headers

// Local Includes
#include "../utils/testing_utilities.h"
#include "../utils/hydro_utilities.h"
#include "../global/global.h"

// =============================================================================
// Local helper functions

/*!
* INDEX OF VARIABLES
* p : pressure
* vx, vy, vz : x, y, and z velocity
* d : density
* E : energy
* T : temperature
* px, py, pz : x, y, and z momentum
* n : number density
*/

namespace
{
    struct TestParams
    {
        double gamma = 5./3.;
        std::vector<double> d {8.4087201154e-100, 1.6756968986e2, 5.4882403847e100};
        std::vector<double> vx {7.0378624601e-100, 7.0829278656e2, 1.8800514112e100};
        std::vector<double> vy {7.3583469014e-100, 5.9283073464e2, 5.2725717864e100};
        std::vector<double> vz {1.7182972216e-100, 8.8417748226e2, 1.5855352639e100};
        std::vector<double> px {8.2340416681e-100, 8.1019429453e2, 5.5062596954e100};
        std::vector<double> py {4.9924582299e-100, 7.1254780684e2, 6.5939640992e100};
        std::vector<double> pz {3.6703192739e-100, 7.5676716066e2, 7.2115881803e100};
        std::vector<double> E {3.0342082433e-100, 7.6976906577e2, 1.9487120853e100};
        std::vector<double> p {2.2244082909e-100, 8.6772951021e2, 6.7261085663e100};
        std::vector<std::string> names{"Small number case", "Medium number case", "Large number case"};
    };
}

TEST(tHYDROSYSTEMHydroUtilsCalcPressureConserved, CorrectInputExpectCorrectOutput) {
    TestParams parameters;
    std::vector<double> fiducial_ps {5, 5, 5};

    for (size_t i = 0; i < parameters.names.size(); i++)
    {
        Real test_ps = hydro_utilities::Calc_Pressure_Conserved(parameters.E.at(i), parameters.d.at(i), parameters.px.at(i), parameters.py.at(i), parameters.pz.at(i), parameters.gamma);

        testingUtilities::checkResults(fiducial_ps.at(i), test_ps, parameters.names.at(i));
    }
}<|endoftext|>