<commit_before>#pragma once
#include <iterator>
#include <algorithm>
#include <experimental/type_traits>
#include "gsl/assert.hpp"

namespace gsl {

// [views.constants], constants
constexpr std::ptrdiff_t dynamic_extent = -1;

template<std::ptrdiff_t Extent>
struct __span_size
{
    template<typename T>
    __span_size(T)
    {}
    constexpr operator ptrdiff_t () const
    {
        return Extent;
    }
    template<typename T>
    auto& operator = (T)
    {
        return *this;
    }
};

template<>
struct __span_size<dynamic_extent>
{
    template<typename T>
    __span_size(T s) : m_value{static_cast<ptrdiff_t>(s)}
    {}
    constexpr operator std::ptrdiff_t () const
    {
        return m_value;
    }
    template<typename T>
    auto& operator = (T s)
    {
        m_value = s;
        return *this;
    }
private:
    std::ptrdiff_t m_value;
};

// A view over a contiguous, single-dimension sequence of objects
template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
class span
{
public:
    // constants and types
    using element_type = ElementType;
    using index_type = std::ptrdiff_t;
    using pointer = element_type*;
    using reference = element_type&;
    using iterator = pointer;
    using const_iterator = const pointer;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    static constexpr index_type extent = Extent;

    // [span.cons], span constructors, copy, assignment, and destructor constexpr span();
    constexpr span(std::nullptr_t) : m_data{nullptr}, m_size{0}
    {}

    constexpr span(pointer ptr, index_type count) : m_data{ptr}, m_size{count}
    {}

    constexpr span(pointer firstElem, pointer lastElem) : m_data{firstElem}, m_size{std::distance(firstElem,lastElem)}
    {}

    template <size_t N>
    constexpr span(element_type (&arr)[N]) : m_data{arr}, m_size{N}
    {}

    template <size_t N>
    constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) : m_data{arr.data()}, m_size{N}
    {}

    template <size_t N>
    constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) : m_data{const_cast<element_type*>(arr.data())}, m_size{N}
    {}

    template <class Container>
    constexpr span(Container& cont) : m_data{reinterpret_cast<element_type*>(cont.data())}, m_size{cont.size()}
    {}

    template <class Container>
    constexpr span(const Container& cont) : m_data{reinterpret_cast<const element_type*>(cont.data())}, m_size{cont.size()}
    {}

    // template <class Container> span(const Container&&) = delete;

    constexpr span(const span& other) noexcept = default;

    constexpr span(span&& other) noexcept = default;

    template <class OtherElementType, ptrdiff_t OtherExtent>
    constexpr span(const span<OtherElementType, OtherExtent>& other) : span<ElementType,Extent>{other.data(), other.size()}
    {
        static_assert(std::is_convertible_v<OtherElementType,ElementType>, "Not convertible");
        static_assert(OtherExtent <= Extent, "Size mismatch");
    }

    template <class OtherElementType, ptrdiff_t OtherExtent>
    constexpr span(span<OtherElementType, OtherExtent>&& other) : span<ElementType,Extent>{other.data(), other.size()}
    {
        static_assert(std::is_convertible_v<OtherElementType,ElementType>, "Not convertible");
        static_assert(Extent == dynamic_extent || OtherExtent <= Extent, "Size mismatch");
    }

    ~span() noexcept = default;

    constexpr span& operator=(const span& other) noexcept = default;

    constexpr span& operator=(span&& other) noexcept = default;

    // [span.sub], span subviews
    template <ptrdiff_t Count>
    constexpr span<element_type, Count> first() const
    {
        return first(Count);
    }

    template <ptrdiff_t Count>
    constexpr span<element_type, Count> last() const
    {
        return last(Count);
    }

    template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
    constexpr span<element_type, Count> subspan() const
    {
        return subspan(Offset, Count);
    }

    constexpr span<element_type, dynamic_extent> first(index_type count) const
    {
        Ensures(count <= m_size);
        return {m_data,count};
    }

    constexpr span<element_type, dynamic_extent> last(index_type count) const
    {
        Ensures(count <= m_size);
        return {m_data + m_size - count, count};
    }

    constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const
    {
        Ensures(offset <= m_size);
        return {m_data + offset, (count == dynamic_extent) ? (m_size - offset) : count};
    }

    // [span.obs], span observers
    constexpr index_type length() const noexcept
    {
        return m_size;
    }

    constexpr index_type size() const noexcept
    {
        return m_size;
    }

    constexpr index_type length_bytes() const noexcept
    {
        return m_size * sizeof(element_type);
    }

    constexpr index_type size_bytes() const noexcept
    {
        return m_size * sizeof(element_type);
    }

    constexpr bool empty() const noexcept
    {
        return !m_size;
    }

    // [span.elem], span element access
    constexpr reference operator[](index_type idx) const
    {
        Ensures(idx < m_size);
        return m_data[idx];
    }

    constexpr reference operator()(index_type idx) const
    {
        Ensures(idx < m_size);
        return m_data[idx];
    }

    constexpr pointer data() const noexcept
    {
        return m_data;
    }

    // [span.iter], span iterator support
    iterator begin() const noexcept
    {
        return m_data;
    }

    iterator end() const noexcept
    {
        return m_data + m_size;
    }

    const_iterator cbegin() const noexcept
    {
        return begin();
    }

    const_iterator cend() const noexcept
    {
        return end();
    }

    reverse_iterator rbegin() const noexcept
    {
        return std::make_reverse_iterator(end());
    }

    reverse_iterator rend() const noexcept
    {
        return std::make_reverse_iterator(begin());
    }

    const_reverse_iterator crbegin() const noexcept
    {
        return std::make_reverse_iterator(cend());
    }

    const_reverse_iterator crend() const noexcept
    {
        return std::make_reverse_iterator(cbegin());
    }

private:

    // exposition only

    pointer m_data;

    __span_size<Extent> m_size;
};

// [span.comparison], span comparison operators
template <class ElementType, ptrdiff_t Extent>
constexpr bool operator==(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::equal(l.cbegin(),l.cend(),r.cbegin(),r.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return !(l == r);
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::lexicographical_compare(l.cbegin(),l.cend(),r.cbegin(),r.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return r == l || r < l;
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::lexicographical_compare(r.cbegin(),r.cend(),l.cbegin(),l.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return r == l || r > l;
}

// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
constexpr span<const std::byte, (Extent == dynamic_extent ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept
{
    return {static_cast<const std::byte*>(s.data()), s.length_bytes()};
}

template <class ElementType, ptrdiff_t Extent>
constexpr span<std::byte, (Extent == dynamic_extent ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writeable_bytes(span<ElementType, Extent> s) noexcept
{
    return {static_cast<std::byte*>(s.data()), s.length_bytes()};
}

//
// make_span() - Utility functions for creating spans
//

template <class ElementType>
span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::index_type count)
{
    return span<ElementType>(ptr, count);
}

template <class ElementType>
span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
{
    return span<ElementType>(firstElem, lastElem);
}

template <class ElementType, std::size_t N>
span<ElementType, N> make_span(ElementType (&arr)[N])
{
    return span<ElementType, N>(arr);
}

template <class Container>
span<typename Container::value_type> make_span(Container& cont)
{
    return span<typename Container::value_type>(cont);
}

template <class Container>
span<const typename Container::value_type> make_span(const Container& cont)
{
    return span<const typename Container::value_type>(cont);
}

template <class Ptr>
span<typename Ptr::element_type> make_span(Ptr& cont, std::ptrdiff_t count)
{
    return span<typename Ptr::element_type>(cont, count);
}

template <class Ptr>
span<typename Ptr::element_type> make_span(Ptr& cont)
{
    return span<typename Ptr::element_type>(cont);
}

} // namespace gsl
<commit_msg>Fixes<commit_after>#pragma once
#include <iterator>
#include <algorithm>
#include <experimental/type_traits>
#include "gsl/assert.hpp"

namespace gsl {

// [views.constants], constants
constexpr std::ptrdiff_t dynamic_extent = -1;

template<std::ptrdiff_t Extent>
struct __span_size
{
    template<typename T>
    __span_size(T)
    {}
    constexpr operator ptrdiff_t () const
    {
        return Extent;
    }
    template<typename T>
    auto& operator = (T)
    {
        return *this;
    }
};

template<>
struct __span_size<dynamic_extent>
{
    template<typename T>
    __span_size(T s) : m_value{static_cast<ptrdiff_t>(s)}
    {}
    constexpr operator std::ptrdiff_t () const
    {
        return m_value;
    }
    template<typename T>
    auto& operator = (T s)
    {
        m_value = s;
        return *this;
    }
private:
    std::ptrdiff_t m_value;
};

// A view over a contiguous, single-dimension sequence of objects
template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
class span
{
public:
    // constants and types
    using element_type = ElementType;
    using index_type = std::ptrdiff_t;
    using pointer = element_type*;
    using reference = element_type&;
    using iterator = pointer;
    using const_iterator = const pointer;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    static constexpr index_type extent = Extent;

    // [span.cons], span constructors, copy, assignment, and destructor constexpr span();
    constexpr span(std::nullptr_t) :
        m_data{nullptr},
        m_size{0}
    {}

    constexpr span(pointer ptr, index_type count) :
        m_data{ptr},
        m_size{count}
    {}

    constexpr span(pointer firstElem, pointer lastElem) :
        m_data{firstElem},
        m_size{std::distance(firstElem,lastElem)}
    {}

    template <size_t N>
    constexpr span(element_type (&arr)[N]) :
        m_data{arr},
        m_size{N}
    {}

    template <size_t N>
    constexpr span(std::array<std::remove_const_t<element_type>, N>& arr) :
        m_data{arr.data()},
        m_size{N}
    {}

    template <size_t N>
    constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) :
        m_data{const_cast<element_type*>(arr.data())},
        m_size{N}
    {}

    template <class Container>
    constexpr span(Container& cont) :
        m_data{reinterpret_cast<element_type*>(cont.data())},
        m_size{cont.size()}
    {}

    template <class Container>
    constexpr span(const Container& cont) :
        m_data{const_cast<element_type*>(reinterpret_cast<const element_type*>(cont.data()))},
        m_size{cont.size()}
    {}

    // template <class Container> span(const Container&&) = delete;

    constexpr span(const span& other) noexcept = default;

    constexpr span(span&& other) noexcept = default;

    template <class OtherElementType, ptrdiff_t OtherExtent>
    constexpr span(const span<OtherElementType, OtherExtent>& other) :
        span<ElementType,Extent>{other.data(), other.size()}
    {
        static_assert(std::is_convertible_v<OtherElementType,ElementType>, "Not convertible");
        static_assert(OtherExtent <= Extent, "Size mismatch");
    }

    template <class OtherElementType, ptrdiff_t OtherExtent>
    constexpr span(span<OtherElementType, OtherExtent>&& other) :
        span<ElementType,Extent>{other.data(), other.size()}
    {
        static_assert(std::is_convertible_v<OtherElementType,ElementType>, "Not convertible");
        static_assert(Extent == dynamic_extent || OtherExtent <= Extent, "Size mismatch");
    }

    ~span() noexcept = default;

    constexpr span& operator=(const span& other) noexcept = default;

    constexpr span& operator=(span&& other) noexcept = default;

    // [span.sub], span subviews
    template <ptrdiff_t Count>
    constexpr span<element_type, Count> first() const
    {
        return first(Count);
    }

    template <ptrdiff_t Count>
    constexpr span<element_type, Count> last() const
    {
        return last(Count);
    }

    template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
    constexpr span<element_type, Count> subspan() const
    {
        return subspan(Offset, Count);
    }

    constexpr span<element_type, dynamic_extent> first(index_type count) const
    {
        Ensures(count <= m_size);
        return {m_data,count};
    }

    constexpr span<element_type, dynamic_extent> last(index_type count) const
    {
        Ensures(count <= m_size);
        return {m_data + m_size - count, count};
    }

    constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const
    {
        Ensures(offset <= m_size);
        return {m_data + offset, (count == dynamic_extent) ? (m_size - offset) : count};
    }

    // [span.obs], span observers
    constexpr index_type length() const noexcept
    {
        return m_size;
    }

    constexpr index_type size() const noexcept
    {
        return m_size;
    }

    constexpr index_type length_bytes() const noexcept
    {
        return m_size * sizeof(element_type);
    }

    constexpr index_type size_bytes() const noexcept
    {
        return m_size * sizeof(element_type);
    }

    constexpr bool empty() const noexcept
    {
        return !m_size;
    }

    // [span.elem], span element access
    constexpr reference operator[](index_type idx) const
    {
        Ensures(idx < m_size);
        return m_data[idx];
    }

    constexpr reference operator()(index_type idx) const
    {
        Ensures(idx < m_size);
        return m_data[idx];
    }

    constexpr pointer data() const noexcept
    {
        return m_data;
    }

    // [span.iter], span iterator support
    iterator begin() const noexcept
    {
        return m_data;
    }

    iterator end() const noexcept
    {
        return m_data + m_size;
    }

    const_iterator cbegin() const noexcept
    {
        return begin();
    }

    const_iterator cend() const noexcept
    {
        return end();
    }

    reverse_iterator rbegin() const noexcept
    {
        return std::make_reverse_iterator(end());
    }

    reverse_iterator rend() const noexcept
    {
        return std::make_reverse_iterator(begin());
    }

    const_reverse_iterator crbegin() const noexcept
    {
        return std::make_reverse_iterator(cend());
    }

    const_reverse_iterator crend() const noexcept
    {
        return std::make_reverse_iterator(cbegin());
    }

private:

    // exposition only

    pointer m_data;

    __span_size<Extent> m_size;
};

// [span.comparison], span comparison operators
template <class ElementType, ptrdiff_t Extent>
constexpr bool operator==(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::equal(l.cbegin(),l.cend(),r.cbegin(),r.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return !(l == r);
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::lexicographical_compare(l.cbegin(),l.cend(),r.cbegin(),r.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return r == l || r < l;
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return std::lexicographical_compare(r.cbegin(),r.cend(),l.cbegin(),l.cend());
}

template <class ElementType, ptrdiff_t Extent>
constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) noexcept
{
    return r == l || r > l;
}

// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
constexpr span<const std::byte, (Extent == dynamic_extent ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept
{
    return {static_cast<const std::byte*>(s.data()), s.length_bytes()};
}

template <class ElementType, ptrdiff_t Extent>
constexpr span<std::byte, (Extent == dynamic_extent ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writeable_bytes(span<ElementType, Extent> s) noexcept
{
    return {static_cast<std::byte*>(s.data()), s.length_bytes()};
}

//
// make_span() - Utility functions for creating spans
//

template <class ElementType>
span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::index_type count)
{
    return span<ElementType>(ptr, count);
}

template <class ElementType>
span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
{
    return span<ElementType>(firstElem, lastElem);
}

template <class ElementType, std::size_t N>
span<ElementType, N> make_span(ElementType (&arr)[N])
{
    return span<ElementType, N>(arr);
}

template <class Container>
span<typename Container::value_type> make_span(Container& cont)
{
    return span<typename Container::value_type>(cont);
}

template <class Container>
span<const typename Container::value_type> make_span(const Container& cont)
{
    return span<const typename Container::value_type>(cont);
}

template <class Ptr>
span<typename Ptr::element_type> make_span(Ptr& cont, std::ptrdiff_t count)
{
    return span<typename Ptr::element_type>(cont, count);
}

template <class Ptr>
span<typename Ptr::element_type> make_span(Ptr& cont)
{
    return span<typename Ptr::element_type>(cont);
}

} // namespace gsl
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-llvm %s -o %t
// RUN: grep "call i32 @_Z5func1i" %t | count 3

extern "C" int printf(...);

static int count;

int func2(int c) { return printf("loading the func2(%d)\n", c); };
int func1(int c) { return printf("loading the func1(%d)\n", c); }

static int loader_1 = func1(++count);

int loader_2 = func2(++count);

static int loader_3 = func1(++count);

int main() {}

int loader_4 = func2(++count);
static int loader_5 = func1(++count);
int loader_6 = func2(++count);

<commit_msg>FileCheckify a grep test.<commit_after>// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-llvm %s -o - | FileCheck %s

extern "C" int printf(...);

static int count;

int func2(int c) { return printf("loading the func2(%d)\n", c); };
int func1(int c) { return printf("loading the func1(%d)\n", c); }

static int loader_1 = func1(++count);
// CHECK: call i32 @_Z5func1i

int loader_2 = func2(++count);

static int loader_3 = func1(++count);
// CHECK: call i32 @_Z5func1i

int main() {}

int loader_4 = func2(++count);
static int loader_5 = func1(++count);
int loader_6 = func2(++count);
// CHECK: call i32 @_Z5func1i

// CHECK-NOT: call i32 @_Z5func1i
<|endoftext|>


<commit_before>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#include <gtest/gtest.h>
#include <DO/Core/EigenExtension.hpp>
#include <DO/Core/MultiArray.hpp>

using namespace DO;
using namespace std;

TEST(DO_Core_Test, eigenExtensionTest)
{
  typedef Matrix2f SuperScalar;
  typedef MultiArray<SuperScalar, 2> Mat2i;
  SuperScalar a; a << 1, 2, 3, 4;
  SuperScalar b; b << 1, 1, 2, 3;

  Mat2i m(2,2);
  Mat2i n(2,2);

  // Initialize the matrices m and n.
  m.array().fill(a);
  n.array().fill(b);

  // Check m
  cout << "Check m" << endl;
  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      //cout << "m(" << i << "," << j << ") = " << endl << m(i,j) << endl;
      EXPECT_EQ(m(i,j), a);
  // Check n
  cout << "Check n" << endl;
  for (int i = 0; i < n.rows(); ++i)
    for (int j = 0; j < n.cols(); ++j)
      //cout << "n(" << i << "," << j << ") = " << endl << n(i,j) << endl;
      EXPECT_EQ(n(i,j), b);

  // Double that matrix
  cout << "m.array() += n.array()" << endl;
  m.array() += n.array();
  // Check that matrix
  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      //cout << "m(" << i << "," << j << ") = " << endl << m(i,j) << endl;
      EXPECT_EQ(m(i,j), (a+b).eval());

  cout << "m(0,0)*n(0,0)=" << endl;
  cout << m(0,0)*n(0,0) << endl;
  EXPECT_EQ(m(0,0)*n(0,0), (a+b)*b);

  // Double that matrix
  cout << "m.array() *= n.array()" << endl;
  m.array() *= n.array();
  // Check that matrix
  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      //cout << "m(" << i << "," << j << ") = " << endl << m(i,j) << endl;
      EXPECT_EQ(m(i,j), (a+b)*b);

  m.matrix() += n.matrix();
  (m.array() * n.array()) + n.array() / m.array();
}

int main(int argc, char** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}<commit_msg>Silence `Core_EigenExtension` test.<commit_after>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#include <gtest/gtest.h>
#include <DO/Core/EigenExtension.hpp>
#include <DO/Core/MultiArray.hpp>

using namespace DO;
using namespace std;

TEST(DO_Core_Test, eigenExtensionTest)
{
  typedef Matrix2f SuperScalar;
  typedef MultiArray<SuperScalar, 2> Mat2i;
  SuperScalar a; a << 1, 2, 3, 4;
  SuperScalar b; b << 1, 1, 2, 3;

  Mat2i m(2,2);
  Mat2i n(2,2);

  // Initialize the matrices m and n.
  m.array().fill(a);
  n.array().fill(b);

  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      EXPECT_EQ(m(i,j), a);

  for (int i = 0; i < n.rows(); ++i)
    for (int j = 0; j < n.cols(); ++j)
      EXPECT_EQ(n(i,j), b);

  // Double that matrix
  m.array() += n.array();
  // Check that matrix
  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      EXPECT_EQ(m(i,j), (a+b).eval());

  EXPECT_EQ(m(0,0)*n(0,0), (a+b)*b);

  // Double that matrix
  m.array() *= n.array();
  // Check that matrix
  for (int i = 0; i < m.rows(); ++i)
    for (int j = 0; j < m.cols(); ++j)
      EXPECT_EQ(m(i,j), (a+b)*b);

  m.matrix() += n.matrix();
  (m.array() * n.array()) + n.array() / m.array();
}

int main(int argc, char** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}<|endoftext|>


<commit_before>#include <QApplication>
#include <QFontDatabase>
#include <QtGlobal>
#include <QFile>
#include <QCommandLineParser>
#include <QFileInfo>
#include <QDir>
#include "neovimconnector.h"
#include "mainwindow.h"
#include "app.h"

/// A log handler for Qt messages, all messages are dumped into the file
/// passed via the NVIM_QT_LOG variable. Some information is only available
/// in debug builds (e.g. qDebug is only called in debug builds).
///
/// In UNIX Qt prints messages to the console output, but in Windows this is
/// the only way to get Qt's debug/warning messages.
void logger(QtMsgType type, const QMessageLogContext& ctx, const QString& msg)
{
	QFile logFile(qgetenv("NVIM_QT_LOG"));
	if (logFile.open(QIODevice::Append | QIODevice::Text)) {
		QTextStream stream(&logFile);
		stream << msg << "\n";
	}
}

#ifdef Q_OS_MAC
bool getLoginEnvironment(const QString& path)
{
	QProcess proc;
	proc.start(path, {"-l", "-c", "env", "-i"});
	if (!proc.waitForFinished()) {
		qDebug() << "Failed to execute shell to get environemnt" << path;
		return false;
	}

	QByteArray out = proc.readAllStandardOutput();
	foreach(const QByteArray& item, out.split('\n')) {
		int index = item.indexOf('=');
		if (index > 0) {
			qputenv(item.mid(0, index), item.mid(index+1));
			qDebug() << item.mid(0, index) << item.mid(index+1);
		}
	}
	return true;
}

void loadLoginEnvironmen()
{
	QByteArray shellPath = qgetenv("SHELL");
	if (!getLoginEnvironment(shellPath)) {
		getLoginEnvironment("/bin/bash");
	}
}
#endif

int main(int argc, char **argv)
{
	NeovimQt::App app(argc, argv);
	app.setApplicationDisplayName("Neovim");
	app.setWindowIcon(QIcon(":/neovim.png"));

	if (!qgetenv("NVIM_QT_LOG").isEmpty()) {
		qInstallMessageHandler(logger);
	}

	QCommandLineParser parser;
	parser.addOption(QCommandLineOption("nvim",
		QCoreApplication::translate("main", "nvim executable path"),
		QCoreApplication::translate("main", "nvim_path"),
		"nvim"));
	parser.addOption(QCommandLineOption("geometry",
		QCoreApplication::translate("main", "Initial window geometry"),
		QCoreApplication::translate("main", "geometry")));
	parser.addOption(QCommandLineOption("maximized",
		QCoreApplication::translate("main", "Maximize the window on startup")));
	parser.addOption(QCommandLineOption("fullscreen",
		QCoreApplication::translate("main", "Open the window in fullscreen on startup")));
	parser.addHelpOption();
	parser.addOption(QCommandLineOption("embed",
		QCoreApplication::translate("main", "Communicate with Neovim over stdin/out")));
	parser.addOption(QCommandLineOption("server",
		QCoreApplication::translate("main", "Connect to existing Neovim instance"),
		QCoreApplication::translate("main", "addr")));

	parser.addPositionalArgument("file",
		QCoreApplication::translate("main", "Edit specified file(s)"), "[file...]");
	parser.addPositionalArgument("...", "Additional arguments are fowarded to Neovim", "[-- ...]");

	int positionalMarker = app.arguments().indexOf("--");
	QStringList neovimArgs;
	neovimArgs << "--cmd";
	neovimArgs << "set termguicolors";
	if (positionalMarker != -1) {
		QStringList args = app.arguments().mid(0, positionalMarker);
		neovimArgs += app.arguments().mid(positionalMarker+1);
		parser.process(args);
	} else {
		parser.process(app.arguments());
	}

	if (parser.isSet("help")) {
		parser.showHelp();
	}

	if (parser.isSet("server") && parser.isSet("embed")) {
		qWarning() << "Options --server and --embed are mutually exclusive\n";
		parser.showHelp();
	}

#ifdef Q_OS_MAC
	// In Mac OS X we can be running off a bundle in which case the user
	// shell environment variabls ($PATH, etc) are not set - try to load them
	loadLoginEnvironmen();
#endif

	NeovimQt::NeovimConnector *c;
	if (parser.isSet("embed")) {
		if (!parser.positionalArguments().isEmpty()
				|| positionalMarker != -1) {
			qWarning() << "--embed does not accept positional arguments\n";
			parser.showHelp();
		}
		c = NeovimQt::NeovimConnector::fromStdinOut();
	} else if (parser.isSet("server")) {
		if (!parser.positionalArguments().isEmpty()
				|| positionalMarker != -1) {
			qWarning() << "--server does not accept positional arguments\n";
			parser.showHelp();
		}
		QString server = parser.value("server");
		c = NeovimQt::NeovimConnector::connectToNeovim(server);
	} else {
		auto path = qgetenv("NVIM_QT_RUNTIME_PATH");
		if (QFileInfo(path).isDir()) {
			neovimArgs.insert(0, "--cmd");
			neovimArgs.insert(1, QString("set rtp+=%1")
					.arg(QString::fromLocal8Bit(path)));
		}
#ifdef NVIM_QT_RUNTIME_PATH
		else if (QFileInfo(NVIM_QT_RUNTIME_PATH).isDir()) {
			neovimArgs.insert(0, "--cmd");
			neovimArgs.insert(1, QString("set rtp+=%1")
					.arg(NVIM_QT_RUNTIME_PATH));
		} else
#endif
		{
			// Look for the runtime relative to the nvim-qt binary
			QDir d = QFileInfo(QCoreApplication::applicationDirPath()).dir();
#ifdef Q_OS_MAC
			// within the bundle at ../Resources/runtime
			d.cd("Resources");
			d.cd("runtime");
#else
			// ../share/nvim-qt/runtime
			d.cd("share");
			d.cd("nvim-qt");
			d.cd("runtime");
#endif

			if (d.exists()) {
				neovimArgs.insert(0, "--cmd");
				neovimArgs.insert(1, QString("set rtp+=%1")
						.arg(d.path()));
			}
		}

		// Pass positional file arguments to Neovim
		neovimArgs.append(parser.positionalArguments());
		c = NeovimQt::NeovimConnector::spawn(neovimArgs, parser.value("nvim"));
	}

#ifdef NEOVIMQT_GUI_WIDGET
	NeovimQt::Shell *win = new NeovimQt::Shell(c);
	win->show();
	if (parser.isSet("fullscreen")) {
		win->showFullScreen();
	} else if (parser.isSet("maximized")) {
		win->showMaximized();
	} else {
		win->show();
	}
#else
	NeovimQt::MainWindow *win = new NeovimQt::MainWindow(c);

	QObject::connect(&app, SIGNAL(openFilesTriggered(const QList<QUrl>)),
		win->shell(), SLOT(openFiles(const QList<QUrl>)));

	if (parser.isSet("fullscreen")) {
		win->delayedShow(NeovimQt::MainWindow::DelayedShow::FullScreen);
	} else if (parser.isSet("maximized")) {
		win->delayedShow(NeovimQt::MainWindow::DelayedShow::Maximized);
	} else {
		win->delayedShow();
	}
#endif
	return app.exec();
}

<commit_msg>GUI: New option --spawn<commit_after>#include <QApplication>
#include <QFontDatabase>
#include <QtGlobal>
#include <QFile>
#include <QCommandLineParser>
#include <QFileInfo>
#include <QDir>
#include "neovimconnector.h"
#include "mainwindow.h"
#include "app.h"

/// A log handler for Qt messages, all messages are dumped into the file
/// passed via the NVIM_QT_LOG variable. Some information is only available
/// in debug builds (e.g. qDebug is only called in debug builds).
///
/// In UNIX Qt prints messages to the console output, but in Windows this is
/// the only way to get Qt's debug/warning messages.
void logger(QtMsgType type, const QMessageLogContext& ctx, const QString& msg)
{
	QFile logFile(qgetenv("NVIM_QT_LOG"));
	if (logFile.open(QIODevice::Append | QIODevice::Text)) {
		QTextStream stream(&logFile);
		stream << msg << "\n";
	}
}

#ifdef Q_OS_MAC
bool getLoginEnvironment(const QString& path)
{
	QProcess proc;
	proc.start(path, {"-l", "-c", "env", "-i"});
	if (!proc.waitForFinished()) {
		qDebug() << "Failed to execute shell to get environemnt" << path;
		return false;
	}

	QByteArray out = proc.readAllStandardOutput();
	foreach(const QByteArray& item, out.split('\n')) {
		int index = item.indexOf('=');
		if (index > 0) {
			qputenv(item.mid(0, index), item.mid(index+1));
			qDebug() << item.mid(0, index) << item.mid(index+1);
		}
	}
	return true;
}

void loadLoginEnvironmen()
{
	QByteArray shellPath = qgetenv("SHELL");
	if (!getLoginEnvironment(shellPath)) {
		getLoginEnvironment("/bin/bash");
	}
}
#endif

int main(int argc, char **argv)
{
	NeovimQt::App app(argc, argv);
	app.setApplicationDisplayName("Neovim");
	app.setWindowIcon(QIcon(":/neovim.png"));

	if (!qgetenv("NVIM_QT_LOG").isEmpty()) {
		qInstallMessageHandler(logger);
	}

	QCommandLineParser parser;
	parser.addOption(QCommandLineOption("nvim",
		QCoreApplication::translate("main", "nvim executable path"),
		QCoreApplication::translate("main", "nvim_path"),
		"nvim"));
	parser.addOption(QCommandLineOption("geometry",
		QCoreApplication::translate("main", "Initial window geometry"),
		QCoreApplication::translate("main", "geometry")));
	parser.addOption(QCommandLineOption("maximized",
		QCoreApplication::translate("main", "Maximize the window on startup")));
	parser.addOption(QCommandLineOption("fullscreen",
		QCoreApplication::translate("main", "Open the window in fullscreen on startup")));
	parser.addHelpOption();
	parser.addOption(QCommandLineOption("embed",
		QCoreApplication::translate("main", "Communicate with Neovim over stdin/out")));
	parser.addOption(QCommandLineOption("server",
		QCoreApplication::translate("main", "Connect to existing Neovim instance"),
		QCoreApplication::translate("main", "addr")));
	parser.addOption(QCommandLineOption("spawn",
		QCoreApplication::translate("main", "Call nvim using the given positional arguments")));

	parser.addPositionalArgument("file",
		QCoreApplication::translate("main", "Edit specified file(s)"), "[file...]");
	parser.addPositionalArgument("...", "Additional arguments are fowarded to Neovim", "[-- ...]");

	int positionalMarker = app.arguments().indexOf("--");
	QStringList neovimArgs;
	QStringList spawnArgs;
	neovimArgs << "--cmd";
	neovimArgs << "set termguicolors";

	int spawn_idx = app.arguments().indexOf("--spawn");
	if (spawn_idx != -1 && (spawn_idx < positionalMarker
				|| positionalMarker == -1)) {
		QStringList args = app.arguments().mid(0, spawn_idx+1);
		spawnArgs = app.arguments().mid(spawn_idx+1);
		parser.process(args);
	} else if (positionalMarker != -1) {
		QStringList args = app.arguments().mid(0, positionalMarker);
		neovimArgs += app.arguments().mid(positionalMarker+1);
		parser.process(args);
	} else {
		parser.process(app.arguments());
	}

	if (parser.isSet("help")) {
		parser.showHelp();
	}

	int exclusive = parser.isSet("server") + parser.isSet("embed") + parser.isSet("spawn");
	if (exclusive > 1) {
		qWarning() << "Options --server, --spawn and --embed are mutually exclusive\n";
		parser.showHelp();
	}

#ifdef Q_OS_MAC
	// In Mac OS X we can be running off a bundle in which case the user
	// shell environment variabls ($PATH, etc) are not set - try to load them
	loadLoginEnvironmen();
#endif

	NeovimQt::NeovimConnector *c;
	if (parser.isSet("embed")) {
		if (!parser.positionalArguments().isEmpty()
				|| positionalMarker != -1) {
			qWarning() << "--embed does not accept positional arguments\n";
			parser.showHelp();
		}
		c = NeovimQt::NeovimConnector::fromStdinOut();
	} else if (parser.isSet("server")) {
		if (!parser.positionalArguments().isEmpty()
				|| positionalMarker != -1) {
			qWarning() << "--server does not accept positional arguments\n";
			parser.showHelp();
		}
		QString server = parser.value("server");
		c = NeovimQt::NeovimConnector::connectToNeovim(server);
	} else if (parser.isSet("spawn")) {
		if (spawnArgs.isEmpty()) {
			qWarning() << "--spawn requires at least one positional argument";
			parser.showHelp();
		}
		QString exe = spawnArgs.at(0);
		c = NeovimQt::NeovimConnector::spawn(spawnArgs.mid(1), exe);
	} else {
		auto path = qgetenv("NVIM_QT_RUNTIME_PATH");
		if (QFileInfo(path).isDir()) {
			neovimArgs.insert(0, "--cmd");
			neovimArgs.insert(1, QString("set rtp+=%1")
					.arg(QString::fromLocal8Bit(path)));
		}
#ifdef NVIM_QT_RUNTIME_PATH
		else if (QFileInfo(NVIM_QT_RUNTIME_PATH).isDir()) {
			neovimArgs.insert(0, "--cmd");
			neovimArgs.insert(1, QString("set rtp+=%1")
					.arg(NVIM_QT_RUNTIME_PATH));
		} else
#endif
		{
			// Look for the runtime relative to the nvim-qt binary
			QDir d = QFileInfo(QCoreApplication::applicationDirPath()).dir();
#ifdef Q_OS_MAC
			// within the bundle at ../Resources/runtime
			d.cd("Resources");
			d.cd("runtime");
#else
			// ../share/nvim-qt/runtime
			d.cd("share");
			d.cd("nvim-qt");
			d.cd("runtime");
#endif

			if (d.exists()) {
				neovimArgs.insert(0, "--cmd");
				neovimArgs.insert(1, QString("set rtp+=%1")
						.arg(d.path()));
			}
		}

		// Pass positional file arguments to Neovim
		neovimArgs.append(parser.positionalArguments());
		c = NeovimQt::NeovimConnector::spawn(neovimArgs, parser.value("nvim"));
	}

#ifdef NEOVIMQT_GUI_WIDGET
	NeovimQt::Shell *win = new NeovimQt::Shell(c);
	win->show();
	if (parser.isSet("fullscreen")) {
		win->showFullScreen();
	} else if (parser.isSet("maximized")) {
		win->showMaximized();
	} else {
		win->show();
	}
#else
	NeovimQt::MainWindow *win = new NeovimQt::MainWindow(c);

	QObject::connect(&app, SIGNAL(openFilesTriggered(const QList<QUrl>)),
		win->shell(), SLOT(openFiles(const QList<QUrl>)));

	if (parser.isSet("fullscreen")) {
		win->delayedShow(NeovimQt::MainWindow::DelayedShow::FullScreen);
	} else if (parser.isSet("maximized")) {
		win->delayedShow(NeovimQt::MainWindow::DelayedShow::Maximized);
	} else {
		win->delayedShow();
	}
#endif
	return app.exec();
}

<|endoftext|>


<commit_before>#include <algorithm>
#include <cassert>
#include <cmath>

#include "hlstrafe.hpp"
#include "util.hpp"

namespace HLStrafe
{
	double MaxAccelTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0)
			return M_PI;

		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - accelspeed;
		if (tmp <= 0.0)
			return M_PI / 2;

		double speed = Length<float, 2>(player.Velocity);
		if (tmp < speed)
			return std::acos(tmp / speed);

		return 0.0;
	}

	double MaxAccelIntoYawTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, double vel_yaw, double yaw)
	{
		assert(postype != PositionType::WATER);

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		if (theta == 0.0 || theta == M_PI)
			return NormalizeRad(yaw - vel_yaw + theta);
		return std::copysign(theta, NormalizeRad(yaw - vel_yaw));
	}

	double MaxAngleTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double speed = Length<float, 2>(player.Velocity);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0) {
			double wishspeed_capped = onground ? wishspeed : 30;
			accelspeed *= -1;
			if (accelspeed >= speed) {
				if (wishspeed_capped >= speed)
					return 0.0;
				else
					return std::acos(wishspeed_capped / speed); // The actual angle needs to be _less_ than this.
			} else {
				if (wishspeed_capped >= speed)
					return std::acos(accelspeed / speed);
				else
					return std::acos(std::min(accelspeed, wishspeed_capped) / speed); // The actual angle needs to be _less_ than this if wishspeed_capped <= accelspeed.
			}
		} else {
			if (accelspeed >= speed)
				return M_PI;
			else
				return std::acos(-1 * accelspeed / speed);
		}
	}

	void VectorFME(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, const double a[2])
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - DotProduct<float, double, 2>(player.Velocity, a);
		if (tmp <= 0.0)
			return;

		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= tmp)
			tmp = accelspeed;

		player.Velocity[0] += a[0] * tmp;
		player.Velocity[1] += a[1] * tmp;
	}

	inline double ButtonsPhi(HLTAS::Button button)
	{
		switch (button) {
		case HLTAS::Button::      FORWARD: return 0;
		case HLTAS::Button:: FORWARD_LEFT: return -M_PI / 4;
		case HLTAS::Button::         LEFT: return -M_PI / 2;
		case HLTAS::Button::    BACK_LEFT: return -3 * M_PI / 2;
		case HLTAS::Button::         BACK: return M_PI;
		case HLTAS::Button::   BACK_RIGHT: return 3 * M_PI / 2;
		case HLTAS::Button::        RIGHT: return M_PI / 2;
		case HLTAS::Button::FORWARD_RIGHT: return M_PI / 4;
		default: return 0;
		}
	}

	static void SideStrafeGeneral(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed,
		HLTAS::Button buttons, double vel_yaw, double theta, bool right, bool safeguard_yaw, float velocities[2][2], double yaws[2])
	{
		assert(postype != PositionType::WATER);

		double phi = ButtonsPhi(buttons);
		phi = right ? phi : -phi;
		theta = right ? theta : -theta;

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double yaw = vel_yaw + phi - theta;
		yaws[0] = AngleModRad(yaw);
		// Very rare case of yaw == anglemod(yaw).
		if (yaws[0] == yaw) {
			// Multiply by 1.5 because the fp precision might make the yaw a value not enough to reach the next anglemod.
			yaws[1] = AngleModRad(yaw + (std::copysign(M_U_RAD, yaw) * 1.5));

			// We need to handle this when we may have yaw equal to the speed change boundary.
			if (safeguard_yaw) {
				// Divide by 2 because it might throw us a value too far back.
				yaws[0] = AngleModRad(yaw - (std::copysign(M_U_RAD, yaw) / 2));
			}
		} else
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD, yaw));

		double avec[2] = { std::cos(yaws[0] - phi), std::sin(yaws[0] - phi) };
		PlayerData pl = player;
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[0]);

		avec[0] = std::cos(yaws[1] - phi);
		avec[1] = std::sin(yaws[1] - phi);
		VecCopy<float, 2>(player.Velocity, pl.Velocity);
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[1]);
	}

	double SideStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw, bool right)
	{
		assert(postype != PositionType::WATER);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		float velocities[2][2];
		double yaws[2];
		SideStrafeGeneral(player, vars, postype, wishspeed, buttons, vel_yaw, theta, right, false, velocities, yaws);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(velocities[0], velocities[0]),
			DotProduct<float, float, 2>(velocities[1], velocities[1])
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(velocities[0], player.Velocity);
			return yaws[0];
		} else {
			VecCopy<float, 2>(velocities[1], player.Velocity);
			return yaws[1];
		}
	}
}
<commit_msg>Correction.<commit_after>#include <algorithm>
#include <cassert>
#include <cmath>

#include "hlstrafe.hpp"
#include "util.hpp"

namespace HLStrafe
{
	double MaxAccelTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0)
			return M_PI;

		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - accelspeed;
		if (tmp <= 0.0)
			return M_PI / 2;

		double speed = Length<float, 2>(player.Velocity);
		if (tmp < speed)
			return std::acos(tmp / speed);

		return 0.0;
	}

	double MaxAccelIntoYawTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, double vel_yaw, double yaw)
	{
		assert(postype != PositionType::WATER);

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		if (theta == 0.0 || theta == M_PI)
			return NormalizeRad(yaw - vel_yaw + theta);
		return std::copysign(theta, NormalizeRad(yaw - vel_yaw));
	}

	double MaxAngleTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double speed = Length<float, 2>(player.Velocity);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0) {
			double wishspeed_capped = onground ? wishspeed : 30;
			accelspeed *= -1;
			if (accelspeed >= speed) {
				if (wishspeed_capped >= speed)
					return 0.0;
				else
					return std::acos(wishspeed_capped / speed); // The actual angle needs to be _less_ than this.
			} else {
				if (wishspeed_capped >= speed)
					return std::acos(accelspeed / speed);
				else
					return std::acos(std::min(accelspeed, wishspeed_capped) / speed); // The actual angle needs to be _less_ than this if wishspeed_capped <= accelspeed.
			}
		} else {
			if (accelspeed >= speed)
				return M_PI;
			else
				return std::acos(-1 * accelspeed / speed);
		}
	}

	void VectorFME(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, const double a[2])
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - DotProduct<float, double, 2>(player.Velocity, a);
		if (tmp <= 0.0)
			return;

		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= tmp)
			tmp = accelspeed;

		player.Velocity[0] += a[0] * tmp;
		player.Velocity[1] += a[1] * tmp;
	}

	inline double ButtonsPhi(HLTAS::Button button)
	{
		switch (button) {
		case HLTAS::Button::      FORWARD: return 0;
		case HLTAS::Button:: FORWARD_LEFT: return -M_PI / 4;
		case HLTAS::Button::         LEFT: return -M_PI / 2;
		case HLTAS::Button::    BACK_LEFT: return -3 * M_PI / 2;
		case HLTAS::Button::         BACK: return M_PI;
		case HLTAS::Button::   BACK_RIGHT: return 3 * M_PI / 2;
		case HLTAS::Button::        RIGHT: return M_PI / 2;
		case HLTAS::Button::FORWARD_RIGHT: return M_PI / 4;
		default: return 0;
		}
	}

	static void SideStrafeGeneral(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed,
		HLTAS::Button buttons, double vel_yaw, double theta, bool right, bool safeguard_yaw, float velocities[2][2], double yaws[2])
	{
		assert(postype != PositionType::WATER);

		double phi = ButtonsPhi(buttons);
		phi = right ? phi : -phi;
		theta = right ? theta : -theta;

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double yaw = vel_yaw + phi - theta;
		yaws[0] = AngleModRad(yaw);
		// Very rare case of yaw == anglemod(yaw).
		if (yaws[0] == yaw) {
			// Multiply by 1.5 because the fp precision might make the yaw a value not enough to reach the next anglemod.
			// Or divide by 2 because it might throw us a value too far back.
			if (yaw >= 0)
				yaws[1] = AngleModRad(yaw + (M_U_RAD * 1.5));
			else
				yaws[1] = AngleModRad(yaw - (M_U_RAD / 2));

			// We need to handle this when we may have yaw equal to the speed change boundary.
			if (safeguard_yaw) {
				if (yaw >= 0)
					yaws[0] = AngleModRad(yaw - (M_U_RAD / 2));
				else
					yaws[0] = AngleModRad(yaw + (M_U_RAD * 1.5));
			}
		} else
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD, yaw));

		double avec[2] = { std::cos(yaws[0] - phi), std::sin(yaws[0] - phi) };
		PlayerData pl = player;
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[0]);

		avec[0] = std::cos(yaws[1] - phi);
		avec[1] = std::sin(yaws[1] - phi);
		VecCopy<float, 2>(player.Velocity, pl.Velocity);
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[1]);
	}

	double SideStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw, bool right)
	{
		assert(postype != PositionType::WATER);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		float velocities[2][2];
		double yaws[2];
		SideStrafeGeneral(player, vars, postype, wishspeed, buttons, vel_yaw, theta, right, false, velocities, yaws);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(velocities[0], velocities[0]),
			DotProduct<float, float, 2>(velocities[1], velocities[1])
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(velocities[0], player.Velocity);
			return yaws[0];
		} else {
			VecCopy<float, 2>(velocities[1], player.Velocity);
			return yaws[1];
		}
	}
}
<|endoftext|>


<commit_before>#include "http/http.hpp"
#include <iostream>
#include <boost/bind.hpp>
#include "logger.hpp"

std::string http_req_t::find_query_param(std::string key) const {
    //TODO this is inefficient we should actually load it all into a map
    for (std::vector<query_parameter_t>::const_iterator it = query_params.begin(); it != query_params.end(); it++) {
        if (it->key == key) return it->val;
    }
    return std::string("");
}

std::string http_req_t::find_header_line(std::string key) const {
    //TODO this is inefficient we should actually load it all into a map
    for (std::vector<header_line_t>::const_iterator it = header_lines.begin(); it != header_lines.end(); it++) {
        if (it->key == key) return it->val;
    }
    return std::string("");
}

int content_length(http_req_t msg) {
    for (std::vector<header_line_t>::iterator it = msg.header_lines.begin(); it != msg.header_lines.end(); it++) {
        if (it->key == std::string("Content-Length"))
            return atoi(it->val.c_str());
    }
    return 0;
}

void http_res_t::add_header_line(std::string const &key, std::string const &val) {
    header_line_t hdr_ln;
    hdr_ln.key = key;
    hdr_ln.val = val;
    header_lines.push_back(hdr_ln);
}

void http_res_t::set_body(std::string const &content_type, std::string const &content) {
    for (std::vector<header_line_t>::iterator it = header_lines.begin(); it != header_lines.end(); it++) {
        rassert(it->key != "Content-Type");
        rassert(it->key != "Conent-Length");
    }
    rassert(body.size() == 0);

    add_header_line("Content-Type", content_type);

    std::ostringstream res;
    res << content.size();
    add_header_line("Content-Length", res.str());

    body = content;
}

typedef std::string::const_iterator str_iterator_type;
typedef http_msg_parser_t<str_iterator_type> str_http_msg_parser_t;

typedef tcp_conn_t::iterator tcp_iterator_type;
typedef http_msg_parser_t<tcp_iterator_type> tcp_http_msg_parser_t;

void test_header_parser() {
    http_req_t res;
    str_http_msg_parser_t http_msg_parser;
    std::string header =
        "GET /foo/bar HTTP/1.1\r\n"
        "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: 0\r\n"
        "\r\n"
        ;
    std::string::const_iterator iter = header.begin();
    std::string::const_iterator end = header.end();
    bool success = parse(iter, end, http_msg_parser, res);
    BREAKPOINT;
    success = true;
}

http_server_t::http_server_t(int port) {
    tcp_listener.reset(new tcp_listener_t(port, boost::bind(&http_server_t::handle_conn, this, _1)));
}

std::string human_readable_status(int code) {
    switch(code) {
    case 200:
        return "OK";
    case 204:
        return "No Content";
    case 400:
        return "Bad Request";
    case 404:
        return "Not Found";
    default:
        unreachable();
    }
}

void write_http_msg(boost::scoped_ptr<tcp_conn_t> &conn, http_res_t const &res) {
    conn->writef("HTTP/%s %d %s\r\n", res.version.c_str(), res.code, human_readable_status(res.code).c_str());
    for (std::vector<header_line_t>::const_iterator it = res.header_lines.begin(); it != res.header_lines.end(); it++) {
        conn->writef("%s: %s\r\n", it->key.c_str(), it->val.c_str());
    }
    conn->writef("\r\n");
    conn->writef("%s", res.body.c_str());
}

void http_server_t::handle_conn(boost::scoped_ptr<tcp_conn_t> &conn) {
    //BREAKPOINT;
    http_req_t req;
    tcp_http_msg_parser_t http_msg_parser;

    //debug(http_msg_parser);

    tcp_iterator_type iter = conn->begin();
    tcp_iterator_type end = conn->end();

    /* parse the request */
    if (parse(iter, end, http_msg_parser, req)) {
        conn->pop(iter);
        const_charslice slc = conn->peek(4);

        if (strncmp(slc.beg, "\r\n\r\n", 4) != 0) {
            goto PARSE_ERROR;
        }
        conn->pop(4);

        slc = conn->peek(content_length(req));
        req.body.append(slc.beg, content_length(req));
        conn->pop(content_length(req));

        logDBG("Request for: %s\n", req.resource.c_str());

        http_res_t res = handle(req);
        res.version = req.version;
        write_http_msg(conn, res);
    }

    return;

PARSE_ERROR:
    http_res_t res;
    res.code = 400;
    write_http_msg(conn, res);
}

test_server_t::test_server_t(int port)
    : http_server_t(port)
{ }

http_res_t test_server_t::handle(const http_req_t &req) {
    http_res_t res;

    res.version = req.version;
    res.code = 200;

    res.add_header_line("Vary", "Accept-Encoding");
    res.add_header_line("Content-Length", "0");

    return res;
}
<commit_msg>Fix problem with assert when writing too big a http body.<commit_after>#include "http/http.hpp"
#include <iostream>
#include <boost/bind.hpp>
#include "logger.hpp"

std::string http_req_t::find_query_param(std::string key) const {
    //TODO this is inefficient we should actually load it all into a map
    for (std::vector<query_parameter_t>::const_iterator it = query_params.begin(); it != query_params.end(); it++) {
        if (it->key == key) return it->val;
    }
    return std::string("");
}

std::string http_req_t::find_header_line(std::string key) const {
    //TODO this is inefficient we should actually load it all into a map
    for (std::vector<header_line_t>::const_iterator it = header_lines.begin(); it != header_lines.end(); it++) {
        if (it->key == key) return it->val;
    }
    return std::string("");
}

int content_length(http_req_t msg) {
    for (std::vector<header_line_t>::iterator it = msg.header_lines.begin(); it != msg.header_lines.end(); it++) {
        if (it->key == std::string("Content-Length"))
            return atoi(it->val.c_str());
    }
    return 0;
}

void http_res_t::add_header_line(std::string const &key, std::string const &val) {
    header_line_t hdr_ln;
    hdr_ln.key = key;
    hdr_ln.val = val;
    header_lines.push_back(hdr_ln);
}

void http_res_t::set_body(std::string const &content_type, std::string const &content) {
    for (std::vector<header_line_t>::iterator it = header_lines.begin(); it != header_lines.end(); it++) {
        rassert(it->key != "Content-Type");
        rassert(it->key != "Conent-Length");
    }
    rassert(body.size() == 0);

    add_header_line("Content-Type", content_type);

    std::ostringstream res;
    res << content.size();
    add_header_line("Content-Length", res.str());

    body = content;
}

typedef std::string::const_iterator str_iterator_type;
typedef http_msg_parser_t<str_iterator_type> str_http_msg_parser_t;

typedef tcp_conn_t::iterator tcp_iterator_type;
typedef http_msg_parser_t<tcp_iterator_type> tcp_http_msg_parser_t;

void test_header_parser() {
    http_req_t res;
    str_http_msg_parser_t http_msg_parser;
    std::string header =
        "GET /foo/bar HTTP/1.1\r\n"
        "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: 0\r\n"
        "\r\n"
        ;
    std::string::const_iterator iter = header.begin();
    std::string::const_iterator end = header.end();
    bool success = parse(iter, end, http_msg_parser, res);
    BREAKPOINT;
    success = true;
}

http_server_t::http_server_t(int port) {
    tcp_listener.reset(new tcp_listener_t(port, boost::bind(&http_server_t::handle_conn, this, _1)));
}

std::string human_readable_status(int code) {
    switch(code) {
    case 200:
        return "OK";
    case 204:
        return "No Content";
    case 400:
        return "Bad Request";
    case 404:
        return "Not Found";
    default:
        unreachable();
    }
}

void write_http_msg(boost::scoped_ptr<tcp_conn_t> &conn, http_res_t const &res) {
    conn->writef("HTTP/%s %d %s\r\n", res.version.c_str(), res.code, human_readable_status(res.code).c_str());
    for (std::vector<header_line_t>::const_iterator it = res.header_lines.begin(); it != res.header_lines.end(); it++) {
        conn->writef("%s: %s\r\n", it->key.c_str(), it->val.c_str());
    }
    conn->writef("\r\n");
    conn->write(res.body.c_str(), res.body.size());
}

void http_server_t::handle_conn(boost::scoped_ptr<tcp_conn_t> &conn) {
    //BREAKPOINT;
    http_req_t req;
    tcp_http_msg_parser_t http_msg_parser;

    //debug(http_msg_parser);

    tcp_iterator_type iter = conn->begin();
    tcp_iterator_type end = conn->end();

    /* parse the request */
    if (parse(iter, end, http_msg_parser, req)) {
        conn->pop(iter);
        const_charslice slc = conn->peek(4);

        if (strncmp(slc.beg, "\r\n\r\n", 4) != 0) {
            goto PARSE_ERROR;
        }
        conn->pop(4);

        slc = conn->peek(content_length(req));
        req.body.append(slc.beg, content_length(req));
        conn->pop(content_length(req));

        logDBG("Request for: %s\n", req.resource.c_str());

        http_res_t res = handle(req);
        res.version = req.version;
        write_http_msg(conn, res);
    }

    return;

PARSE_ERROR:
    http_res_t res;
    res.code = 400;
    write_http_msg(conn, res);
}

test_server_t::test_server_t(int port)
    : http_server_t(port)
{ }

http_res_t test_server_t::handle(const http_req_t &req) {
    http_res_t res;

    res.version = req.version;
    res.code = 200;

    res.add_header_line("Vary", "Accept-Encoding");
    res.add_header_line("Content-Length", "0");

    return res;
}
<|endoftext|>


<commit_before>#include "net.hpp"
#include "net_gpu.hpp"
#include "net_cpu.hpp"
#include "net_raw_utils.hpp"

#include <gtest/gtest.h>

TEST(gpu_utils, raw_to_gpu_and_back) {
  Raw_Matrix r;
  r.n_rows = 10;
  r.n_cols = 30;
  r.data = new float[100];
  for (int i=0; i < 100; i++) {
    r.data[i] = i;
  }

  Raw_Matrix * d_r = matrix_to_gpu(r);
  Raw_Matrix back_r =  matrix_to_cpu(d_r);

  ASSERT_EQ(back_r.n_cols, r.n_cols);
  ASSERT_EQ(back_r.n_rows, r.n_rows);
  for (int i=0; i < 100; i++) {
    ASSERT_EQ(back_r.data[i], r.data[i]);
  }
  delete r.data;
}

TEST(gpu_utils, raw_net_to_gpu_and_back) {
  FeedForward_Network<> f(5, 10, 4);
  randomize(f);
  for (int i = 0; i < 4; ++i) {
    f.activation_input[i] = i*1;
    f.activation_hidden[i] = i*2;
    f.activation_output[i] = i*3;
  }

  Raw_FeedForward_Network<> raw_net = convert_to_raw(f);

  Raw_FeedForward_Network<> * d_net = network_to_gpu(raw_net);

  int input_size = raw_net.input_size;
  int output_size = raw_net.output_size;
  int hidden_size = raw_net.hidden_size;
  float inputToHidden4 = raw_net.weights_inputToHidden.data[4];
  float inputToHidden5 = raw_net.weights_inputToHidden.data[5];

  float hiddenToOutput4 = raw_net.weights_hiddenToOutput.data[4];
  float hiddenToOutput5 = raw_net.weights_hiddenToOutput.data[5];

  float hiddenToOutput_n_rows = raw_net.weights_hiddenToOutput.n_rows;
  float hiddenToOutput_n_cols = raw_net.weights_hiddenToOutput.n_cols;
  float inputToHidden_n_rows = raw_net.weights_inputToHidden.n_rows;
  float inputToHidden_n_cols = raw_net.weights_inputToHidden.n_cols;

  //Fudge the data to ensure its properly reset
  raw_net.input_size = 1;
  raw_net.output_size = 2;
  raw_net.hidden_size = 1;

  raw_net.weights_inputToHidden.data[4] = -1;
  raw_net.weights_inputToHidden.data[5] = -1;

  raw_net.weights_hiddenToOutput.data[4] = -1;
  raw_net.weights_hiddenToOutput.data[5] = -1;

  raw_net.weights_hiddenToOutput.n_rows = -1;
  raw_net.weights_hiddenToOutput.n_cols = -1;

  raw_net.weights_inputToHidden.n_rows = -1;
  raw_net.weights_inputToHidden.n_cols = -1;

  for (int i = 0; i < 4; ++i) {
    raw_net.activation_input.data[i] = -1;
    raw_net.activation_hidden.data[i] = -1;
    raw_net.activation_output.data[i] = -1;
  }

  //re copy back from gpu
  network_to_cpu(d_net, raw_net);

  ASSERT_EQ(raw_net.input_size, input_size);
  ASSERT_EQ(raw_net.output_size, output_size);
  ASSERT_EQ(raw_net.hidden_size, hidden_size);

  ASSERT_EQ(raw_net.weights_inputToHidden.data[4], inputToHidden4);
  ASSERT_EQ(raw_net.weights_inputToHidden.data[5], inputToHidden5);

  ASSERT_EQ(raw_net.weights_hiddenToOutput.data[4], hiddenToOutput4);
  ASSERT_EQ(raw_net.weights_hiddenToOutput.data[5], hiddenToOutput5);

  ASSERT_EQ(raw_net.weights_hiddenToOutput.n_rows, hiddenToOutput_n_rows);
  ASSERT_EQ(raw_net.weights_hiddenToOutput.n_cols, hiddenToOutput_n_cols);

  ASSERT_EQ(raw_net.weights_inputToHidden.n_rows, inputToHidden_n_rows);
  ASSERT_EQ(raw_net.weights_inputToHidden.n_cols, inputToHidden_n_cols);

  for (int i = 0; i < 4; ++i) {
    ASSERT_FLOAT_EQ(raw_net.activation_input.data[i], i*1.f);
    ASSERT_FLOAT_EQ(raw_net.activation_hidden.data[i], i*2.f);
    ASSERT_FLOAT_EQ(raw_net.activation_output.data[i], i*3.f);
  }
}

TEST(net_gpu, predict) {
  FeedForward_Network<> f(2, 2, 1);
  f.resize_activation(3);
  f.weights_inputToHidden.at(0,0) = -1;
  f.weights_inputToHidden.at(1,0) = -.1;
  f.weights_inputToHidden.at(0,1) = .1;
  f.weights_inputToHidden.at(1,1) = 1;

  f.weights_hiddenToOutput.at(0,0) = 1;
  f.weights_hiddenToOutput.at(1,0) = 0;

  Raw_FeedForward_Network<> raw_net = convert_to_raw(f);
  Raw_FeedForward_Network<> * d_net = network_to_gpu(raw_net);

  arma::Mat<float> inputs(3, 2);
  inputs.at(0,0) = 0;
  inputs.at(0,1) = 0;

  inputs.at(1,0) = 1;
  inputs.at(1,1) = 0;

  inputs.at(2,0) = 0;
  inputs.at(2,1) = 1;

  Raw_Matrix raw_inputs = to_raw(inputs);
  Raw_Matrix * d_inputs = matrix_to_gpu(raw_inputs);

  int num_trials = 3;
  int input_size = 2;
  int hidden_size = 2;
  int output_size = 1;
  calculate_activation(num_trials, input_size, hidden_size, output_size, d_net, d_inputs);

  network_to_cpu(d_net, raw_net);
  //input activations
  ASSERT_EQ(raw_net.activation_input.n_rows, 3);
  ASSERT_EQ(raw_net.activation_input.n_cols, 2);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(0,0), 0);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(1,0), 1);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(2,1), 1);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(2,0), 0);

  //hidden activations (calculated with sigmoid activation
  ASSERT_EQ(raw_net.activation_hidden.n_rows, 3);
  ASSERT_EQ(raw_net.activation_hidden.n_cols, 2);

  ASSERT_NEAR(raw_net.activation_hidden.at(0,0), 0.5, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(0,1), 0.5, .1);

  ASSERT_NEAR(raw_net.activation_hidden.at(1,0), 0.27, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(1,1), .52, .1);

  ASSERT_NEAR(raw_net.activation_hidden.at(2,0), 0.4750, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(2,1), 0.7311, .1);

  //output activations (calculated with signmoid)
  ASSERT_EQ(raw_net.activation_output.n_rows, 3);
  ASSERT_EQ(raw_net.activation_output.n_cols, 1);

  ASSERT_NEAR(raw_net.activation_output.at(0,0), 0.62, .1);
  ASSERT_NEAR(raw_net.activation_output.at(1,0), 0.57, .1);
  ASSERT_NEAR(raw_net.activation_output.at(2,0), 0.62, .1);

}
<commit_msg>remove whitespace<commit_after>#include "net.hpp"
#include "net_gpu.hpp"
#include "net_cpu.hpp"
#include "net_raw_utils.hpp"

#include <gtest/gtest.h>

TEST(gpu_utils, raw_to_gpu_and_back) {
  Raw_Matrix r;
  r.n_rows = 10;
  r.n_cols = 30;
  r.data = new float[100];
  for (int i=0; i < 100; i++) {
    r.data[i] = i;
  }

  Raw_Matrix * d_r = matrix_to_gpu(r);
  Raw_Matrix back_r =  matrix_to_cpu(d_r);

  ASSERT_EQ(back_r.n_cols, r.n_cols);
  ASSERT_EQ(back_r.n_rows, r.n_rows);
  for (int i=0; i < 100; i++) {
    ASSERT_EQ(back_r.data[i], r.data[i]);
  }
  delete r.data;
}

TEST(gpu_utils, raw_net_to_gpu_and_back) {
  FeedForward_Network<> f(5, 10, 4);
  randomize(f);
  for (int i = 0; i < 4; ++i) {
    f.activation_input[i] = i*1;
    f.activation_hidden[i] = i*2;
    f.activation_output[i] = i*3;
  }

  Raw_FeedForward_Network<> raw_net = convert_to_raw(f);

  Raw_FeedForward_Network<> * d_net = network_to_gpu(raw_net);

  int input_size = raw_net.input_size;
  int output_size = raw_net.output_size;
  int hidden_size = raw_net.hidden_size;
  float inputToHidden4 = raw_net.weights_inputToHidden.data[4];
  float inputToHidden5 = raw_net.weights_inputToHidden.data[5];

  float hiddenToOutput4 = raw_net.weights_hiddenToOutput.data[4];
  float hiddenToOutput5 = raw_net.weights_hiddenToOutput.data[5];

  float hiddenToOutput_n_rows = raw_net.weights_hiddenToOutput.n_rows;
  float hiddenToOutput_n_cols = raw_net.weights_hiddenToOutput.n_cols;
  float inputToHidden_n_rows = raw_net.weights_inputToHidden.n_rows;
  float inputToHidden_n_cols = raw_net.weights_inputToHidden.n_cols;

  //Fudge the data to ensure its properly reset
  raw_net.input_size = 1;
  raw_net.output_size = 2;
  raw_net.hidden_size = 1;

  raw_net.weights_inputToHidden.data[4] = -1;
  raw_net.weights_inputToHidden.data[5] = -1;

  raw_net.weights_hiddenToOutput.data[4] = -1;
  raw_net.weights_hiddenToOutput.data[5] = -1;

  raw_net.weights_hiddenToOutput.n_rows = -1;
  raw_net.weights_hiddenToOutput.n_cols = -1;

  raw_net.weights_inputToHidden.n_rows = -1;
  raw_net.weights_inputToHidden.n_cols = -1;

  for (int i = 0; i < 4; ++i) {
    raw_net.activation_input.data[i] = -1;
    raw_net.activation_hidden.data[i] = -1;
    raw_net.activation_output.data[i] = -1;
  }

  //re copy back from gpu
  network_to_cpu(d_net, raw_net);

  ASSERT_EQ(raw_net.input_size, input_size);
  ASSERT_EQ(raw_net.output_size, output_size);
  ASSERT_EQ(raw_net.hidden_size, hidden_size);

  ASSERT_EQ(raw_net.weights_inputToHidden.data[4], inputToHidden4);
  ASSERT_EQ(raw_net.weights_inputToHidden.data[5], inputToHidden5);

  ASSERT_EQ(raw_net.weights_hiddenToOutput.data[4], hiddenToOutput4);
  ASSERT_EQ(raw_net.weights_hiddenToOutput.data[5], hiddenToOutput5);

  ASSERT_EQ(raw_net.weights_hiddenToOutput.n_rows, hiddenToOutput_n_rows);
  ASSERT_EQ(raw_net.weights_hiddenToOutput.n_cols, hiddenToOutput_n_cols);

  ASSERT_EQ(raw_net.weights_inputToHidden.n_rows, inputToHidden_n_rows);
  ASSERT_EQ(raw_net.weights_inputToHidden.n_cols, inputToHidden_n_cols);

  for (int i = 0; i < 4; ++i) {
    ASSERT_FLOAT_EQ(raw_net.activation_input.data[i], i*1.f);
    ASSERT_FLOAT_EQ(raw_net.activation_hidden.data[i], i*2.f);
    ASSERT_FLOAT_EQ(raw_net.activation_output.data[i], i*3.f);
  }
}

TEST(net_gpu, predict) {
  FeedForward_Network<> f(2, 2, 1);
  f.resize_activation(3);
  f.weights_inputToHidden.at(0,0) = -1;
  f.weights_inputToHidden.at(1,0) = -.1;
  f.weights_inputToHidden.at(0,1) = .1;
  f.weights_inputToHidden.at(1,1) = 1;

  f.weights_hiddenToOutput.at(0,0) = 1;
  f.weights_hiddenToOutput.at(1,0) = 0;

  Raw_FeedForward_Network<> raw_net = convert_to_raw(f);
  Raw_FeedForward_Network<> * d_net = network_to_gpu(raw_net);

  arma::Mat<float> inputs(3, 2);
  inputs.at(0,0) = 0;
  inputs.at(0,1) = 0;

  inputs.at(1,0) = 1;
  inputs.at(1,1) = 0;

  inputs.at(2,0) = 0;
  inputs.at(2,1) = 1;

  Raw_Matrix raw_inputs = to_raw(inputs);
  Raw_Matrix * d_inputs = matrix_to_gpu(raw_inputs);

  int num_trials = 3;
  int input_size = 2;
  int hidden_size = 2;
  int output_size = 1;
  calculate_activation(num_trials, input_size, hidden_size, output_size, d_net, d_inputs);

  network_to_cpu(d_net, raw_net);
  //input activations
  ASSERT_EQ(raw_net.activation_input.n_rows, 3);
  ASSERT_EQ(raw_net.activation_input.n_cols, 2);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(0,0), 0);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(1,0), 1);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(2,1), 1);
  ASSERT_FLOAT_EQ(raw_net.activation_input.at(2,0), 0);

  //hidden activations (calculated with sigmoid activation
  ASSERT_EQ(raw_net.activation_hidden.n_rows, 3);
  ASSERT_EQ(raw_net.activation_hidden.n_cols, 2);

  ASSERT_NEAR(raw_net.activation_hidden.at(0,0), 0.5, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(0,1), 0.5, .1);

  ASSERT_NEAR(raw_net.activation_hidden.at(1,0), 0.27, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(1,1), .52, .1);

  ASSERT_NEAR(raw_net.activation_hidden.at(2,0), 0.4750, .1);
  ASSERT_NEAR(raw_net.activation_hidden.at(2,1), 0.7311, .1);

  //output activations (calculated with signmoid)
  ASSERT_EQ(raw_net.activation_output.n_rows, 3);
  ASSERT_EQ(raw_net.activation_output.n_cols, 1);

  ASSERT_NEAR(raw_net.activation_output.at(0,0), 0.62, .1);
  ASSERT_NEAR(raw_net.activation_output.at(1,0), 0.57, .1);
  ASSERT_NEAR(raw_net.activation_output.at(2,0), 0.62, .1);
}
<|endoftext|>


<commit_before>#pragma once
#include <utils/debug_utils.hh>

#include <algorithm>
#include <list>
#include <memory>

namespace data
{

template<typename T>
class Node
{
public:
    Node(const std::shared_ptr<Node> &parent, const std::shared_ptr<T> &item) :
        parent_(parent), item_(item) { }

    virtual ~Node() = default;

    void add_child(const std::shared_ptr<Node> &child)
    {
        children_.push_back(child);
    }

    bool remove_child(const std::shared_ptr<Node> &child)
    {
        auto it = children_.begin();
        bool found_child = false;
        while (it != children_.end())
        {
            if (*it == child)
            {
                it = children_.erase(it);
                found_child = true;
                // Continue search in case child was added more than once.
            }
            else
            {
                ++it;
            }
        }
        return found_child;
    }

    bool has_child(const std::shared_ptr<Node> &child) const
    {
        for (const auto &Node : children_)
        {
            if (Node == child)
            {
                return true;
            }
        }
        return false;
    }

    bool has_item(const std::shared_ptr<T> &item) const
    {
        if (item_ && item_ == item)
        {
            return true;
        }
        return false;
    }

    size_t num_children() const { return children_.size(); }

    //
    // Accessors
    //

    // Shared ptr to the parent node.
    std::shared_ptr<Node> parent() const { return parent_; }
    // Return a copy so others are not holding references to stored shared pointers.
    // (Everyone gets their own shared pointer)
    std::list<std::shared_ptr<Node>> children() const { return children_; }
    // Access the payload in the node.
    std::shared_ptr<T> item() const { return item_; }

    //
    // Setters
    //
    void set_parent(const std::shared_ptr<Node> &parent) { parent_ = parent; }
    void set_item(const std::shared_ptr<T> &item) { item_ = item; }

private:
    std::shared_ptr<Node> parent_ = nullptr;
    std::list<std::shared_ptr<Node>> children_ = {};

    std::shared_ptr<T> item_ = nullptr;
};

template <typename T>
class Tree
{
public:
    using NodePtr = std::shared_ptr<Node<T>>;

    Tree() : root_(nullptr) { }

    Tree(const std::shared_ptr<T> &root_item)
    {
        root_ = std::make_shared<Node<T>>(nullptr, root_item);
        add_leaf(root_);
    }

    Tree(const NodePtr &root_node)
    {
        root_ = root_node;
        if (root_)
        {
            find_leaves(root_);
        }
    }

    virtual ~Tree() = default;

    NodePtr root() const {return root_;}

    // Adds a child node to the parent containing the "item" as payload.
    // The child is then added to the list of leaf nodes.
    // The shared_ptr to the child is returned.
    NodePtr add_child(NodePtr &parent, const std::shared_ptr<T> &item)
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        NodePtr child = std::make_shared<Node<T>>(parent, item);
        IS_TRUE(child);
        parent->add_child(child);
        add_leaf(child);
        IS_TRUE(child);
        return child;
    }

    // Erases the node and all it's children recursively.
    void erase(NodePtr &node)
    {
       // Confirm the tree has been initialized.
       IS_TRUE(root_);
       erase_recursive(node);
       cleanup_leaves();
    }

    // Pops the node, returning a valid subtree.
    Tree pop(NodePtr &node)
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        // Remove itself from the parent. If the parent has already cleared its
        // children list, this will do nothing.
        node->parent()->remove_child(node);

        // We may have popped off leaves so clear the leaves list and recurse to
        // find the leaves again.
        // (We could alternatively recurse the popped tree and remove those from
        // the leaves list).
        leaves_.clear();
        find_leaves(root_);

        return Tree(node);
    }

    // Return a copy so others are not holding references to stored shared pointers.
    // (Everyone gets their own shared pointer)
    std::list<NodePtr> leaf_nodes() const
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        return leaves_;
    }

    size_t num_leaf_nodes() const { return leaves_.size(); }

    // Call the ostream operator for each item or payload in each node to generate a
    // printable string representing the tree structure.
    std::string display_string(const NodePtr &node = nullptr) const
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        if (node)
        {
            return display_string(node, "");
        }
        return display_string(root_, "");
    }

private:
    NodePtr root_ = nullptr;
    std::list<NodePtr> leaves_ = {};

    // Adds to the leaves list and cleanups any in the list that have children nodes
    // (therefore not actually leaves).
    void add_leaf(const NodePtr &node)
    {
        leaves_.push_back(node);
        cleanup_leaves();
    }

    // Erases the node and all it's children recursively.
    void erase_recursive(NodePtr &node)
    {
        auto children = node->children();
        // Clear the shared pointers being held.
        node->children().clear();
        for (auto &child : children)
        {
            erase_recursive(child);
        }

        // Remove itself from the parent. If the parent has already cleared its
        // children list, this will do nothing.
        node->parent()->remove_child(node);

        // Clear the shared_ptr to the parent.
        node->set_parent(nullptr);

        // Clear the shared_ptr to the item payload.
        node->set_item(nullptr);
        remove_from_leaves_list(node);
    }

    // Remove node from leaves list if it is there.
    void remove_from_leaves_list(NodePtr &node)
    {
        leaves_.erase(
            std::remove_if(leaves_.begin(), leaves_.end(), [&node](const NodePtr &node_cmp)
                {
                    IS_TRUE(node_cmp);
                    return node == node_cmp;
                }
            ),
            leaves_.end()
        );
    }

    // Removes any items in the leaves list that have children nodes.
    void cleanup_leaves()
    {
        leaves_.erase(
            std::remove_if(leaves_.begin(), leaves_.end(), [](const NodePtr &node)
                {
                    IS_TRUE(node);
                    return node->num_children() > 0;
                }
            ),
            leaves_.end()
        );
    }

    // Searches the tree to find leaf nodes and adds them to the leaves list.
    void find_leaves(const NodePtr &start)
    {
        if (start->num_children() == 0)
        {
            leaves_.push_back(start);
        }
        else
        {
            const auto children = start->children();
            for (const auto &child : children)
            {
                IS_TRUE(child);
                find_leaves(child);
            }
        }
    }

    // Traverse the tree recursively depth-first and call the ostream operator for
    // each item or payload in each node.
    std::string display_string(const NodePtr &node, const std::string &spacing) const
    {
        const std::string endl = "\n";

        std::ostringstream oss;
        oss << *node->item() << endl;
        auto children = node->children();

        for (const auto &child : children)
        {
            IS_TRUE(child);
            oss << spacing << "> " << display_string(child, spacing + "  ");
        }

        return oss.str();
    }

};

} // namespace data.

<commit_msg>tree now supports depth storage of the node in the node<commit_after>#pragma once
#include <utils/debug_utils.hh>

#include <algorithm>
#include <list>
#include <memory>

namespace data
{

template<typename T>
class Node
{
public:
    constexpr static int UNSET_DEPTH = -1;

    Node(const std::shared_ptr<Node> &parent, const std::shared_ptr<T> &item, int depth = UNSET_DEPTH) :
        depth_(depth), parent_(parent), item_(item) { }

    virtual ~Node() = default;

    void add_child(const std::shared_ptr<Node> &child)
    {
        children_.push_back(child);
    }

    bool remove_child(const std::shared_ptr<Node> &child)
    {
        auto it = children_.begin();
        bool found_child = false;
        while (it != children_.end())
        {
            if (*it == child)
            {
                it = children_.erase(it);
                found_child = true;
                // Continue search in case child was added more than once.
            }
            else
            {
                ++it;
            }
        }
        return found_child;
    }

    bool has_child(const std::shared_ptr<Node> &child) const
    {
        for (const auto &Node : children_)
        {
            if (Node == child)
            {
                return true;
            }
        }
        return false;
    }

    bool has_item(const std::shared_ptr<T> &item) const
    {
        if (item_ && item_ == item)
        {
            return true;
        }
        return false;
    }

    size_t num_children() const { return children_.size(); }

    //
    // Accessors
    //

    // Shared ptr to the parent node.
    std::shared_ptr<Node> parent() const { return parent_; }
    // Return a copy so others are not holding references to stored shared pointers.
    // (Everyone gets their own shared pointer)
    std::list<std::shared_ptr<Node>> children() const { return children_; }
    // Access the payload in the node.
    std::shared_ptr<T> item() const { return item_; }
    // Get the depth of the Node. -1 implies the depth was not set.
    int depth() const { return depth_; }

    //
    // Setters
    //
    void set_parent(const std::shared_ptr<Node> &parent) { parent_ = parent; }
    void set_item(const std::shared_ptr<T> &item) { item_ = item; }
    void set_depth(int depth) { depth_ = depth; }

private:
    int depth_ = UNSET_DEPTH; // Depth in the tree.

    std::shared_ptr<Node> parent_ = nullptr;
    std::list<std::shared_ptr<Node>> children_ = {};

    std::shared_ptr<T> item_ = nullptr;
};

template <typename T>
class Tree
{
public:
    using NodePtr = std::shared_ptr<Node<T>>;

    Tree() : root_(nullptr) { }

    Tree(const std::shared_ptr<T> &root_item)
    {
        root_ = std::make_shared<Node<T>>(nullptr, root_item, 0);
        add_leaf(root_);
    }

    Tree(const NodePtr &root_node)
    {
        root_ = root_node;
        if (root_)
        {
            // We may need to renumber the depth of the tree if the root node already has children.
            find_leaves(root_, true, 0);
        }
    }

    virtual ~Tree() = default;

    NodePtr root() const {return root_;}

    // Adds a child node to the parent containing the "item" as payload.
    // The child is then added to the list of leaf nodes.
    // The shared_ptr to the child is returned.
    NodePtr add_child(NodePtr &parent, const std::shared_ptr<T> &item)
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        NodePtr child = std::make_shared<Node<T>>(parent, item, parent->depth()+1);
        IS_TRUE(child);
        parent->add_child(child);
        add_leaf(child);
        IS_TRUE(child);
        return child;
    }

    // Erases the node and all it's children recursively.
    void erase(NodePtr &node)
    {
       // Confirm the tree has been initialized.
       IS_TRUE(root_);
       erase_recursive(node);
       cleanup_leaves();
    }

    // Pops the node, returning a valid subtree.
    Tree pop(NodePtr &node)
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        // Remove itself from the parent. If the parent has already cleared its
        // children list, this will do nothing.
        node->parent()->remove_child(node);

        // We may have popped off leaves so clear the leaves list and recurse to
        // find the leaves again.
        // (We could alternatively recurse the popped tree and remove those from
        // the leaves list).
        leaves_.clear();
        find_leaves(root_);

        return Tree(node);
    }

    // Return a copy so others are not holding references to stored shared pointers.
    // (Everyone gets their own shared pointer)
    std::list<NodePtr> leaf_nodes() const
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        return leaves_;
    }

    size_t num_leaf_nodes() const { return leaves_.size(); }

    // Call the ostream operator for each item or payload in each node to generate a
    // printable string representing the tree structure.
    std::string display_string(const NodePtr &node = nullptr) const
    {
        // Confirm the tree has been initialized.
        IS_TRUE(root_);

        if (node)
        {
            return display_string(node, "");
        }
        return display_string(root_, "");
    }

private:
    NodePtr root_ = nullptr;
    std::list<NodePtr> leaves_ = {};

    // Adds to the leaves list and cleanups any in the list that have children nodes
    // (therefore not actually leaves).
    void add_leaf(const NodePtr &node)
    {
        leaves_.push_back(node);
        cleanup_leaves();
    }

    // Erases the node and all it's children recursively.
    void erase_recursive(NodePtr &node)
    {
        auto children = node->children();
        // Clear the shared pointers being held.
        node->children().clear();
        for (auto &child : children)
        {
            erase_recursive(child);
        }

        // Remove itself from the parent. If the parent has already cleared its
        // children list, this will do nothing.
        node->parent()->remove_child(node);

        // Clear the shared_ptr to the parent.
        node->set_parent(nullptr);

        // Clear the shared_ptr to the item payload.
        node->set_item(nullptr);
        remove_from_leaves_list(node);
    }

    // Remove node from leaves list if it is there.
    void remove_from_leaves_list(NodePtr &node)
    {
        leaves_.erase(
            std::remove_if(leaves_.begin(), leaves_.end(), [&node](const NodePtr &node_cmp)
                {
                    IS_TRUE(node_cmp);
                    return node == node_cmp;
                }
            ),
            leaves_.end()
        );
    }

    // Removes any items in the leaves list that have children nodes.
    void cleanup_leaves()
    {
        leaves_.erase(
            std::remove_if(leaves_.begin(), leaves_.end(), [](const NodePtr &node)
                {
                    IS_TRUE(node);
                    return node->num_children() > 0;
                }
            ),
            leaves_.end()
        );
    }

    // Searches the tree to find leaf nodes and adds them to the leaves list.
    // If renumber is >= 0, assumes start node is of depth renumber and assigns depths to each of the node in
    // the tree following start node.
    void find_leaves(const NodePtr &start, bool renumber = false, int renumber_start = -1)
    {
        if (renumber)
        {
            start->set_depth(renumber_start);
        }

        if (start->num_children() == 0)
        {
            leaves_.push_back(start);
        }
        else
        {
            const auto children = start->children();
            for (const auto &child : children)
            {
                IS_TRUE(child);
                find_leaves(child, renumber, renumber_start + 1);
            }
        }
    }

    // Traverse the tree recursively depth-first and call the ostream operator for
    // each item or payload in each node.
    std::string display_string(const NodePtr &node, const std::string &spacing) const
    {
        const std::string endl = "\n";

        std::ostringstream oss;
        oss << "(" << node->depth() << ") " << *node->item() << endl;
        auto children = node->children();

        for (const auto &child : children)
        {
            IS_TRUE(child);
            oss << spacing << "> " <<  display_string(child, spacing + "  ");
        }

        return oss.str();
    }

};

} // namespace data.

<|endoftext|>