<commit_before>#pragma once

#include <array>
#include <vector>
#include <ostream>
#include <cstring>

#ifdef DEBUG
#	include <iostream>
#endif

#include "util.hpp"
#include "debug.hpp"

namespace utki{

/**
 * @brief span template class.
 * This class is a wrapper of continuous memory span, it encapsulates pointer to memory block and size of that memory block.
 * It does not own the memory.
 * This is a replacement of std::span when C++'20 is not available.
 */
template <class T> class span final{
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* iterator;
	typedef const value_type* const_iterator;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;
	typedef std::reverse_iterator<iterator> reverse_iterator;
	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

private:
	pointer buf = nullptr;
	size_type buf_size = 0;

public:
	span(const span&) = default;
	span& operator=(const span&) = default;

	/**
	 * @brief Create a span object.
	 * Creates a span object which wraps given memory buffer of specified size.
	 * Note, the memory will not be freed upon this Buffer object destruction,
	 * Buffer does not own the memory.
	 * @param p - pointer to the memory buffer.
	 * @param s - size of the memory buffer.
	 */
	span(pointer p, size_type s)noexcept :
			buf(p),
			buf_size(s)
	{}

	span()noexcept{}

	/**
	 * @brief Constructor for automatic conversion from nullptr.
     */
	span(std::nullptr_t)noexcept :
			buf(nullptr),
			buf_size(0)
	{}

	/**
	 * @brief for internal use only.
	 * This class is not supposed to be used by users.
	 */
	class dummy_span_class{
	public:
		T* data(){return nullptr;}
		size_t size(){return 0;}
	};

	/**
	 * @brief Constructor for automatic conversion to span<const T>.
	 * @param sp - span to convert.
	 */
	span(const span<
			typename std::conditional<
					std::is_const<T>::value,
					typename std::remove_const<T>::type,
					dummy_span_class
				>::type
		>& sp) :
			buf(sp.data()),
			buf_size(sp.size())
	{}

	/**
	 * @brief get span size.
	 * @return number of elements in the span.
	 */
	size_type size()const noexcept{
		return this->buf_size;
	}

	/**
	 * @brief Check if span is empty.
	 * @return true if the span is empty.
	 * @return false if the span is not empty.
	 */
	bool empty()const noexcept{
		return this->size() == 0;
	}

	/**
	 * @brief get size of span in bytes.
	 * @return size of array in bytes.
	 */
	size_type size_bytes()const noexcept{
		return this->size() * sizeof(value_type);
	}

	/**
	 * @brief access specified element of the span.
	 * Const version of operator[].
	 * @param i - element index.
	 * @return reference to i'th element of the span.
	 */
	const_reference operator[](size_type i)const noexcept{
		ASSERT(i < this->size())
		return this->buf[i];
	}

	/**
	 * @brief access specified element of the span.
	 * @param i - element index.
	 * @return reference to i'th element of the span.
	 */
	reference operator[](size_type i)noexcept{
		ASSERT(i < this->size(), [&](auto&o){o << "operator[](" << i << "): index out of bounds";})
		return this->buf[i];
	}

	/**
	 * @brief get iterator to first element of the span.
	 * @return iterator to first element of the span.
	 */
	iterator begin()noexcept{
		return this->buf;
	}

	/**
	 * @brief get iterator of the first element of the span.
	 * @return iterator of the first element of the span.
	 */
	const_iterator begin()const noexcept{
		return this->cbegin();
	}

	/**
	 * @brief get const iterator of the first element of the span.
	 * @return const iterator of the first element of the span.
	 */
	const_iterator cbegin()const noexcept{
		return this->buf;
	}

	/**
	 * @brief get iterator to "after last" element of the span.
	 * @return iterator to "after last" element of the span.
	 */
	iterator end()noexcept{
		return this->buf + this->buf_size;
	}

	/**
	 * @brief get const iterator to "after last" element of the span.
	 * @return const iterator to "after last" element of the span.
	 */
	const_iterator end()const noexcept{
		return this->cend();
	}

	/**
	 * @brief get const iterator to "after last" element of the span.
	 * @return const iterator to "after last" element of the span.
	 */
	const_iterator cend()const noexcept{
		return this->buf + this->buf_size;
	}

	const_reverse_iterator crbegin()const noexcept{
		return const_reverse_iterator(this->end());
	}

	const_reverse_iterator crend()const noexcept{
		return const_reverse_iterator(this->begin());
	}

	reverse_iterator rbegin()noexcept{
		return reverse_iterator(this->end());
	}

	const_reverse_iterator rbegin()const noexcept{
		return const_reverse_iterator(this->end());
	}

	reverse_iterator rend()noexcept{
		return reverse_iterator(this->begin());
	}

	const_reverse_iterator rend()const noexcept{
		return const_reverse_iterator(this->begin());
	}

	pointer data()noexcept{
		return this->buf;
	}

	const_pointer data()const noexcept{
		return this->buf;
	}

	value_type& front()noexcept{
		ASSERT(!this->empty())
		return this->operator[](0);
	}

	const value_type& front()const noexcept{
		ASSERT(!this->empty())
		return this->operator[](0);
	}

	value_type& back()noexcept{
		ASSERT(!this->empty())
		return this->operator[](this->size() - 1);
	}

	const value_type& back()const noexcept{
		ASSERT(!this->empty())
		return this->operator[](this->size() - 1);
	}

	span subspan(
			size_type offset,
			size_type count = std::numeric_limits<size_type>::max()
		)const noexcept
	{
		pointer new_p = offset > this->size() ? this->end() : this->data() + offset;
		ASSERT(new_p <= this->end())
		size_type max_new_s = this->end() - new_p;
		size_type new_s = count > max_new_s ? max_new_s : count;
		ASSERT(new_p + new_s <= this->end())
		return span(new_p, new_s);
	}

	/**
	 * @brief Checks if pointer points somewhere within the span.
	 * @param p - pointer to check.
	 * @return true - if pointer passed as argument points somewhere within the span.
	 * @return false otherwise.
	 */
	bool overlaps(const_pointer p)const noexcept{
		return this->begin() <= p && p <= (this->end() - 1);
	}

	friend std::ostream& operator<<(std::ostream& s, const span<T>& buf){
		for(auto& e : buf){
			s << e;
		}
		return s;
	}
};

template <class T> inline utki::span<T> make_span(std::nullptr_t){
	return utki::span<T>(nullptr);
}

template <class T> inline utki::span<T> make_span(T* buf, size_t size){
	return utki::span<T>(buf, size);
}

template <class T, std::size_t array_size> inline utki::span<T> make_span(std::array<T, array_size>& a){
	return make_span(a.size() == 0 ? nullptr : a.data(), a.size());
}

template <class T, std::size_t array_size> inline utki::span<const T> make_span(const std::array<T, array_size>& a){
	return make_span(a.size() == 0 ? nullptr : a.data(), a.size());
}

template <class T> inline utki::span<T> make_span(std::vector<T>& v){
	return make_span(v.size() == 0 ? nullptr : v.data(), v.size());
}

template <class T> inline utki::span<const T> make_span(const std::vector<T>& v){
	return make_span(v.size() == 0 ? nullptr : v.data(), v.size());
}

/**
 * @brief Make span representing contents of a basic_string.
 * @param s - string to make the span from.
 * @return span of the string contents.
 */
template <class T> inline utki::span<const T> make_span(const std::basic_string<T>& s){
	return make_span(s.size() == 0 ? nullptr : s.data(), s.size());
}

/**
 * @brief Make span from zero-terminated string.
 * @param str - zero-terminated string to make span from.
 * @return span representing contents of the string.
 */
inline utki::span<const char> make_span(const char* str){
	return make_span(str, strlen(str));
}

}
<commit_msg>undefine the max macro<commit_after>#pragma once

#include <array>
#include <vector>
#include <ostream>
#include <cstring>

#ifdef DEBUG
#	include <iostream>
#endif

#include "util.hpp"
#include "debug.hpp"

// undefine the max macro in case it is defined (e.g. by windows.h)
#ifdef max
#	undef max
#endif

namespace utki{

/**
 * @brief span template class.
 * This class is a wrapper of continuous memory span, it encapsulates pointer to memory block and size of that memory block.
 * It does not own the memory.
 * This is a replacement of std::span when C++'20 is not available.
 */
template <class T> class span final{
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* iterator;
	typedef const value_type* const_iterator;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;
	typedef std::reverse_iterator<iterator> reverse_iterator;
	typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

private:
	pointer buf = nullptr;
	size_type buf_size = 0;

public:
	span(const span&) = default;
	span& operator=(const span&) = default;

	/**
	 * @brief Create a span object.
	 * Creates a span object which wraps given memory buffer of specified size.
	 * Note, the memory will not be freed upon this Buffer object destruction,
	 * Buffer does not own the memory.
	 * @param p - pointer to the memory buffer.
	 * @param s - size of the memory buffer.
	 */
	span(pointer p, size_type s)noexcept :
			buf(p),
			buf_size(s)
	{}

	span()noexcept{}

	/**
	 * @brief Constructor for automatic conversion from nullptr.
     */
	span(std::nullptr_t)noexcept :
			buf(nullptr),
			buf_size(0)
	{}

	/**
	 * @brief for internal use only.
	 * This class is not supposed to be used by users.
	 */
	class dummy_span_class{
	public:
		T* data(){return nullptr;}
		size_t size(){return 0;}
	};

	/**
	 * @brief Constructor for automatic conversion to span<const T>.
	 * @param sp - span to convert.
	 */
	span(const span<
			typename std::conditional<
					std::is_const<T>::value,
					typename std::remove_const<T>::type,
					dummy_span_class
				>::type
		>& sp) :
			buf(sp.data()),
			buf_size(sp.size())
	{}

	/**
	 * @brief get span size.
	 * @return number of elements in the span.
	 */
	size_type size()const noexcept{
		return this->buf_size;
	}

	/**
	 * @brief Check if span is empty.
	 * @return true if the span is empty.
	 * @return false if the span is not empty.
	 */
	bool empty()const noexcept{
		return this->size() == 0;
	}

	/**
	 * @brief get size of span in bytes.
	 * @return size of array in bytes.
	 */
	size_type size_bytes()const noexcept{
		return this->size() * sizeof(value_type);
	}

	/**
	 * @brief access specified element of the span.
	 * Const version of operator[].
	 * @param i - element index.
	 * @return reference to i'th element of the span.
	 */
	const_reference operator[](size_type i)const noexcept{
		ASSERT(i < this->size())
		return this->buf[i];
	}

	/**
	 * @brief access specified element of the span.
	 * @param i - element index.
	 * @return reference to i'th element of the span.
	 */
	reference operator[](size_type i)noexcept{
		ASSERT(i < this->size(), [&](auto&o){o << "operator[](" << i << "): index out of bounds";})
		return this->buf[i];
	}

	/**
	 * @brief get iterator to first element of the span.
	 * @return iterator to first element of the span.
	 */
	iterator begin()noexcept{
		return this->buf;
	}

	/**
	 * @brief get iterator of the first element of the span.
	 * @return iterator of the first element of the span.
	 */
	const_iterator begin()const noexcept{
		return this->cbegin();
	}

	/**
	 * @brief get const iterator of the first element of the span.
	 * @return const iterator of the first element of the span.
	 */
	const_iterator cbegin()const noexcept{
		return this->buf;
	}

	/**
	 * @brief get iterator to "after last" element of the span.
	 * @return iterator to "after last" element of the span.
	 */
	iterator end()noexcept{
		return this->buf + this->buf_size;
	}

	/**
	 * @brief get const iterator to "after last" element of the span.
	 * @return const iterator to "after last" element of the span.
	 */
	const_iterator end()const noexcept{
		return this->cend();
	}

	/**
	 * @brief get const iterator to "after last" element of the span.
	 * @return const iterator to "after last" element of the span.
	 */
	const_iterator cend()const noexcept{
		return this->buf + this->buf_size;
	}

	const_reverse_iterator crbegin()const noexcept{
		return const_reverse_iterator(this->end());
	}

	const_reverse_iterator crend()const noexcept{
		return const_reverse_iterator(this->begin());
	}

	reverse_iterator rbegin()noexcept{
		return reverse_iterator(this->end());
	}

	const_reverse_iterator rbegin()const noexcept{
		return const_reverse_iterator(this->end());
	}

	reverse_iterator rend()noexcept{
		return reverse_iterator(this->begin());
	}

	const_reverse_iterator rend()const noexcept{
		return const_reverse_iterator(this->begin());
	}

	pointer data()noexcept{
		return this->buf;
	}

	const_pointer data()const noexcept{
		return this->buf;
	}

	value_type& front()noexcept{
		ASSERT(!this->empty())
		return this->operator[](0);
	}

	const value_type& front()const noexcept{
		ASSERT(!this->empty())
		return this->operator[](0);
	}

	value_type& back()noexcept{
		ASSERT(!this->empty())
		return this->operator[](this->size() - 1);
	}

	const value_type& back()const noexcept{
		ASSERT(!this->empty())
		return this->operator[](this->size() - 1);
	}

	span subspan(
			size_type offset,
			size_type count = std::numeric_limits<size_type>::max()
		)const noexcept
	{
		pointer new_p = offset > this->size() ? this->end() : this->data() + offset;
		ASSERT(new_p <= this->end())
		size_type max_new_s = this->end() - new_p;
		size_type new_s = count > max_new_s ? max_new_s : count;
		ASSERT(new_p + new_s <= this->end())
		return span(new_p, new_s);
	}

	/**
	 * @brief Checks if pointer points somewhere within the span.
	 * @param p - pointer to check.
	 * @return true - if pointer passed as argument points somewhere within the span.
	 * @return false otherwise.
	 */
	bool overlaps(const_pointer p)const noexcept{
		return this->begin() <= p && p <= (this->end() - 1);
	}

	friend std::ostream& operator<<(std::ostream& s, const span<T>& buf){
		for(auto& e : buf){
			s << e;
		}
		return s;
	}
};

template <class T> inline utki::span<T> make_span(std::nullptr_t){
	return utki::span<T>(nullptr);
}

template <class T> inline utki::span<T> make_span(T* buf, size_t size){
	return utki::span<T>(buf, size);
}

template <class T, std::size_t array_size> inline utki::span<T> make_span(std::array<T, array_size>& a){
	return make_span(a.size() == 0 ? nullptr : a.data(), a.size());
}

template <class T, std::size_t array_size> inline utki::span<const T> make_span(const std::array<T, array_size>& a){
	return make_span(a.size() == 0 ? nullptr : a.data(), a.size());
}

template <class T> inline utki::span<T> make_span(std::vector<T>& v){
	return make_span(v.size() == 0 ? nullptr : v.data(), v.size());
}

template <class T> inline utki::span<const T> make_span(const std::vector<T>& v){
	return make_span(v.size() == 0 ? nullptr : v.data(), v.size());
}

/**
 * @brief Make span representing contents of a basic_string.
 * @param s - string to make the span from.
 * @return span of the string contents.
 */
template <class T> inline utki::span<const T> make_span(const std::basic_string<T>& s){
	return make_span(s.size() == 0 ? nullptr : s.data(), s.size());
}

/**
 * @brief Make span from zero-terminated string.
 * @param str - zero-terminated string to make span from.
 * @return span representing contents of the string.
 */
inline utki::span<const char> make_span(const char* str){
	return make_span(str, strlen(str));
}

}
<|endoftext|>


<commit_before><commit_msg>Make sure the output file is closed before committing<commit_after><|endoftext|>


<commit_before>// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/parser/cpdf_object.h"

#include <algorithm>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcrt/fx_string.h"
#include "third_party/base/stl_util.h"

CPDF_Object::~CPDF_Object() {}

CPDF_Object* CPDF_Object::GetDirect() const {
  return const_cast<CPDF_Object*>(this);
}

CPDF_Object* CPDF_Object::CloneObjectNonCyclic(bool bDirect) const {
  std::set<const CPDF_Object*> visited_objs;
  return CloneNonCyclic(bDirect, &visited_objs);
}

CPDF_Object* CPDF_Object::CloneDirectObject() const {
  return CloneObjectNonCyclic(true);
}

CPDF_Object* CPDF_Object::CloneNonCyclic(
    bool bDirect,
    std::set<const CPDF_Object*>* pVisited) const {
  return Clone();
}

void CPDF_Object::Release() {
  if (m_ObjNum)
    return;

  delete this;
}

CFX_ByteString CPDF_Object::GetString() const {
  return CFX_ByteString();
}

CFX_WideString CPDF_Object::GetUnicodeText() const {
  return CFX_WideString();
}

FX_FLOAT CPDF_Object::GetNumber() const {
  return 0;
}

int CPDF_Object::GetInteger() const {
  return 0;
}

CPDF_Dictionary* CPDF_Object::GetDict() const {
  return nullptr;
}

void CPDF_Object::SetString(const CFX_ByteString& str) {
  ASSERT(FALSE);
}

bool CPDF_Object::IsArray() const {
  return false;
}

bool CPDF_Object::IsBoolean() const {
  return false;
}

bool CPDF_Object::IsDictionary() const {
  return false;
}

bool CPDF_Object::IsName() const {
  return false;
}

bool CPDF_Object::IsNumber() const {
  return false;
}

bool CPDF_Object::IsReference() const {
  return false;
}

bool CPDF_Object::IsStream() const {
  return false;
}

bool CPDF_Object::IsString() const {
  return false;
}

CPDF_Array* CPDF_Object::AsArray() {
  return nullptr;
}

const CPDF_Array* CPDF_Object::AsArray() const {
  return nullptr;
}

CPDF_Boolean* CPDF_Object::AsBoolean() {
  return nullptr;
}

const CPDF_Boolean* CPDF_Object::AsBoolean() const {
  return nullptr;
}

CPDF_Dictionary* CPDF_Object::AsDictionary() {
  return nullptr;
}

const CPDF_Dictionary* CPDF_Object::AsDictionary() const {
  return nullptr;
}

CPDF_Name* CPDF_Object::AsName() {
  return nullptr;
}

const CPDF_Name* CPDF_Object::AsName() const {
  return nullptr;
}

CPDF_Number* CPDF_Object::AsNumber() {
  return nullptr;
}

const CPDF_Number* CPDF_Object::AsNumber() const {
  return nullptr;
}

CPDF_Reference* CPDF_Object::AsReference() {
  return nullptr;
}

const CPDF_Reference* CPDF_Object::AsReference() const {
  return nullptr;
}

CPDF_Stream* CPDF_Object::AsStream() {
  return nullptr;
}

const CPDF_Stream* CPDF_Object::AsStream() const {
  return nullptr;
}

CPDF_String* CPDF_Object::AsString() {
  return nullptr;
}

const CPDF_String* CPDF_Object::AsString() const {
  return nullptr;
}
<commit_msg>Re-enable CHECK() than only 0-numbered objects are released.<commit_after>// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/parser/cpdf_object.h"

#include <algorithm>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcrt/fx_string.h"
#include "third_party/base/stl_util.h"

CPDF_Object::~CPDF_Object() {}

CPDF_Object* CPDF_Object::GetDirect() const {
  return const_cast<CPDF_Object*>(this);
}

CPDF_Object* CPDF_Object::CloneObjectNonCyclic(bool bDirect) const {
  std::set<const CPDF_Object*> visited_objs;
  return CloneNonCyclic(bDirect, &visited_objs);
}

CPDF_Object* CPDF_Object::CloneDirectObject() const {
  return CloneObjectNonCyclic(true);
}

CPDF_Object* CPDF_Object::CloneNonCyclic(
    bool bDirect,
    std::set<const CPDF_Object*>* pVisited) const {
  return Clone();
}

void CPDF_Object::Release() {
  CHECK(!m_ObjNum);
  delete this;
}

CFX_ByteString CPDF_Object::GetString() const {
  return CFX_ByteString();
}

CFX_WideString CPDF_Object::GetUnicodeText() const {
  return CFX_WideString();
}

FX_FLOAT CPDF_Object::GetNumber() const {
  return 0;
}

int CPDF_Object::GetInteger() const {
  return 0;
}

CPDF_Dictionary* CPDF_Object::GetDict() const {
  return nullptr;
}

void CPDF_Object::SetString(const CFX_ByteString& str) {
  ASSERT(FALSE);
}

bool CPDF_Object::IsArray() const {
  return false;
}

bool CPDF_Object::IsBoolean() const {
  return false;
}

bool CPDF_Object::IsDictionary() const {
  return false;
}

bool CPDF_Object::IsName() const {
  return false;
}

bool CPDF_Object::IsNumber() const {
  return false;
}

bool CPDF_Object::IsReference() const {
  return false;
}

bool CPDF_Object::IsStream() const {
  return false;
}

bool CPDF_Object::IsString() const {
  return false;
}

CPDF_Array* CPDF_Object::AsArray() {
  return nullptr;
}

const CPDF_Array* CPDF_Object::AsArray() const {
  return nullptr;
}

CPDF_Boolean* CPDF_Object::AsBoolean() {
  return nullptr;
}

const CPDF_Boolean* CPDF_Object::AsBoolean() const {
  return nullptr;
}

CPDF_Dictionary* CPDF_Object::AsDictionary() {
  return nullptr;
}

const CPDF_Dictionary* CPDF_Object::AsDictionary() const {
  return nullptr;
}

CPDF_Name* CPDF_Object::AsName() {
  return nullptr;
}

const CPDF_Name* CPDF_Object::AsName() const {
  return nullptr;
}

CPDF_Number* CPDF_Object::AsNumber() {
  return nullptr;
}

const CPDF_Number* CPDF_Object::AsNumber() const {
  return nullptr;
}

CPDF_Reference* CPDF_Object::AsReference() {
  return nullptr;
}

const CPDF_Reference* CPDF_Object::AsReference() const {
  return nullptr;
}

CPDF_Stream* CPDF_Object::AsStream() {
  return nullptr;
}

const CPDF_Stream* CPDF_Object::AsStream() const {
  return nullptr;
}

CPDF_String* CPDF_Object::AsString() {
  return nullptr;
}

const CPDF_String* CPDF_Object::AsString() const {
  return nullptr;
}
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 —
            Vladimír Vondruš <mosra@centrum.cz>
        2020 — Nghia Truong <nghiatruong.vn@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

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

#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Pointer.h>
#include <Magnum/Mesh.h>
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Matrix4.h>
#include <Magnum/MeshTools/Interleave.h>
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/SceneGraph/Object.h>
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/Shaders/VertexColor.h>

#include "ArcBall.h"
#include "ArcBallCamera.h"

namespace Magnum { namespace Examples {

using Object3D = SceneGraph::Object<SceneGraph::MatrixTransformation3D>;
using Scene3D = SceneGraph::Scene<SceneGraph::MatrixTransformation3D>;

using namespace Math::Literals;

class ArcBallExample: public Platform::Application {
    public:
        explicit ArcBallExample(const Arguments& arguments);

    private:
        void drawEvent() override;
        void viewportEvent(ViewportEvent& event) override;
        void keyPressEvent(KeyEvent& event) override;
        void mousePressEvent(MouseEvent& event) override;
        void mouseMoveEvent(MouseMoveEvent& event) override;
        void mouseScrollEvent(MouseScrollEvent& event) override;

        Scene3D _scene;
        SceneGraph::DrawableGroup3D _drawables;
        GL::Mesh _mesh{NoCreate};
        Shaders::VertexColor3D _shader{NoCreate};
        Containers::Pointer<ArcBallCamera> _arcballCamera;
};

class VertexColorDrawable: public SceneGraph::Drawable3D {
    public:
        explicit VertexColorDrawable(Object3D& object,
            Shaders::VertexColor3D& shader, GL::Mesh& mesh,
            SceneGraph::DrawableGroup3D& drawables):
                SceneGraph::Drawable3D{object, &drawables},
                _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setTransformationProjectionMatrix(
                camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::VertexColor3D& _shader;
        GL::Mesh& _mesh;
};

ArcBallExample::ArcBallExample(const Arguments& arguments) :
    Platform::Application{arguments, NoCreate}
{
    /* Setup window */
    {
        const Vector2 dpiScaling = this->dpiScaling({});
        Configuration conf;
        conf.setTitle("Magnum ArcBall Camera Example")
            .setSize(conf.size(), dpiScaling)
            .setWindowFlags(Configuration::WindowFlag::Resizable);
        GLConfiguration glConf;
        glConf.setSampleCount(dpiScaling.max() < 2.0f ? 8 : 2);
        if(!tryCreate(conf, glConf)) {
            create(conf, glConf.setSampleCount(0));
        }

        SDL_CaptureMouse(SDL_TRUE);
    }

    GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
    GL::Renderer::enable(GL::Renderer::Feature::FaceCulling);

    /* Setup the cube with vertex color */
    {
        const Containers::Array<Vector3> cubePositions{Containers::InPlaceInit, {
            /* front */
            {-1.0f, -1.0f,  1.0f},
            { 1.0f, -1.0f,  1.0f},
            { 1.0f,  1.0f,  1.0f},
            {-1.0f,  1.0f,  1.0f},
            /* back */
            {-1.0f, -1.0f, -1.0f},
            { 1.0f, -1.0f, -1.0f},
            { 1.0f,  1.0f, -1.0f},
            {-1.0f,  1.0f, -1.0f}
        }};

        const Containers::Array<Color3> cubeColors{Containers::InPlaceInit, {
            /* front colors */
            0x00ffff_rgbf,
            0x0000ff_rgbf,
            0x000000_rgbf,
            0x00ff00_rgbf,
            /* back colors */
            0xffff00_rgbf,
            0xffffff_rgbf,
            0xff00ff_rgbf,
            0xff0000_rgbf,
        }};

        const Containers::Array<char> cubeIndices{Containers::InPlaceInit, {
            /* front */
            0, 1, 2, 2, 3, 0,
            /* right */
            1, 5, 6, 6, 2, 1,
            /* back */
            7, 6, 5, 5, 4, 7,
            /* left */
            4, 0, 3, 3, 7, 4,
            /* bottom */
            4, 5, 1, 1, 0, 4,
            /* top */
            3, 2, 6, 6, 7, 3
        }};

        GL::Buffer vertexBuffer;
        GL::Buffer indexBuffer;
        vertexBuffer.setData(MeshTools::interleave(cubePositions, cubeColors));
        indexBuffer.setData(cubeIndices);

        _mesh = GL::Mesh{};
        _mesh.setCount(cubeIndices.size())
            .addVertexBuffer(std::move(vertexBuffer), 0,
                Shaders::VertexColor3D::Position{},
                Shaders::VertexColor3D::Color3{})
            .setIndexBuffer(std::move(indexBuffer), 0, MeshIndexType::UnsignedByte);

        _shader = Shaders::VertexColor3D{};
        new VertexColorDrawable{*(new Object3D{ &_scene }), _shader, _mesh, _drawables};
    }

    /* Set up the camera */
    {
        /* Setup the arcball after the camera objects */
        const Vector3 eye = Vector3::zAxis(-10.0f);
        const Vector3 center{};
        const Vector3 up = Vector3::yAxis();
        _arcballCamera.emplace(_scene, eye, center, up, 45.0_degf,
            windowSize(), framebufferSize());
    }

    /* Start the timer, loop at 60 Hz max */
    setSwapInterval(1);
    setMinimalLoopPeriod(16);
}

void ArcBallExample::drawEvent() {
    GL::defaultFramebuffer.clear(
        GL::FramebufferClear::Color|GL::FramebufferClear::Depth);

    /* Call arcball update in every frame. This will do nothing if the camera
       has not been changed. Otherwise, camera transformation will be
       propagated into the camera objects. */

    bool camChanged = _arcballCamera->update();
    _arcballCamera->draw(_drawables);
    swapBuffers();

    if(camChanged) redraw();
}

void ArcBallExample::viewportEvent(ViewportEvent& event) {
    GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()});

    _arcballCamera->reshape(event.windowSize(), event.framebufferSize());
}

void ArcBallExample::keyPressEvent(KeyEvent& event) {
    switch(event.key()) {
        case KeyEvent::Key::Plus:
        case KeyEvent::Key::NumAdd:
            _arcballCamera->zoom(1.0f);
            break;
        case KeyEvent::Key::Minus:
        case KeyEvent::Key::NumSubtract:
            _arcballCamera->zoom(-1.0f);
            break;
        case KeyEvent::Key::Left:
            _arcballCamera->translateDelta(Vector2::xAxis(-0.1f));
            break;
        case KeyEvent::Key::Right:
            _arcballCamera->translateDelta(Vector2::xAxis(0.1f));
            break;
        case KeyEvent::Key::Up:
            _arcballCamera->translateDelta(Vector2::yAxis(0.1f));
            break;
        case KeyEvent::Key::Down:
            _arcballCamera->translateDelta(Vector2::yAxis(-0.1f));
            break;

        case KeyEvent::Key::L:
            _arcballCamera->setLagging(_arcballCamera->lagging() > 0.0f ?
                0.0f : 0.85f);
            break;
        case KeyEvent::Key::R:
            _arcballCamera->reset();
            break;

        default: return;
    }

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mousePressEvent(MouseEvent& event) {
    if(event.button() != MouseEvent::Button::Left &&
       event.button() != MouseEvent::Button::Right) return;

    _arcballCamera->initTransformation(event.position());

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mouseMoveEvent(MouseMoveEvent& event) {
    if(event.buttons() & MouseMoveEvent::Button::Left)
        _arcballCamera->rotate(event.position());
    else if(event.buttons() & MouseMoveEvent::Button::Right)
        _arcballCamera->translate(event.position());
    else return;

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mouseScrollEvent(MouseScrollEvent& event) {
    const Float delta = event.offset().y();
    if(Math::abs(delta) < 1.0e-2f) return;

    _arcballCamera->zoom(delta);

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::ArcBallExample)
<commit_msg>arcball: directly interleave the cube data w/o any allocations.<commit_after>/*
    This file is part of Magnum.

    Original authors — credit is appreciated but not required:

        2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 —
            Vladimír Vondruš <mosra@centrum.cz>
        2020 — Nghia Truong <nghiatruong.vn@gmail.com>

    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute
    this software, either in source code form or as a compiled binary, for any
    purpose, commercial or non-commercial, and by any means.

    In jurisdictions that recognize copyright laws, the author or authors of
    this software dedicate any and all copyright interest in the software to
    the public domain. We make this dedication for the benefit of the public
    at large and to the detriment of our heirs and successors. We intend this
    dedication to be an overt act of relinquishment in perpetuity of all
    present and future rights to this software under copyright law.

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

#include <Corrade/Containers/Pointer.h>
#include <Magnum/Mesh.h>
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Matrix4.h>
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/SceneGraph/Object.h>
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/Shaders/VertexColor.h>

#include "ArcBall.h"
#include "ArcBallCamera.h"

namespace Magnum { namespace Examples {

using Object3D = SceneGraph::Object<SceneGraph::MatrixTransformation3D>;
using Scene3D = SceneGraph::Scene<SceneGraph::MatrixTransformation3D>;

using namespace Math::Literals;

class ArcBallExample: public Platform::Application {
    public:
        explicit ArcBallExample(const Arguments& arguments);

    private:
        void drawEvent() override;
        void viewportEvent(ViewportEvent& event) override;
        void keyPressEvent(KeyEvent& event) override;
        void mousePressEvent(MouseEvent& event) override;
        void mouseMoveEvent(MouseMoveEvent& event) override;
        void mouseScrollEvent(MouseScrollEvent& event) override;

        Scene3D _scene;
        SceneGraph::DrawableGroup3D _drawables;
        GL::Mesh _mesh{NoCreate};
        Shaders::VertexColor3D _shader{NoCreate};
        Containers::Pointer<ArcBallCamera> _arcballCamera;
};

class VertexColorDrawable: public SceneGraph::Drawable3D {
    public:
        explicit VertexColorDrawable(Object3D& object,
            Shaders::VertexColor3D& shader, GL::Mesh& mesh,
            SceneGraph::DrawableGroup3D& drawables):
                SceneGraph::Drawable3D{object, &drawables},
                _shader(shader), _mesh(mesh) {}

        void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) {
            _shader.setTransformationProjectionMatrix(
                camera.projectionMatrix()*transformation);
            _mesh.draw(_shader);
        }

    private:
        Shaders::VertexColor3D& _shader;
        GL::Mesh& _mesh;
};

ArcBallExample::ArcBallExample(const Arguments& arguments) :
    Platform::Application{arguments, NoCreate}
{
    /* Setup window */
    {
        const Vector2 dpiScaling = this->dpiScaling({});
        Configuration conf;
        conf.setTitle("Magnum ArcBall Camera Example")
            .setSize(conf.size(), dpiScaling)
            .setWindowFlags(Configuration::WindowFlag::Resizable);
        GLConfiguration glConf;
        glConf.setSampleCount(dpiScaling.max() < 2.0f ? 8 : 2);
        if(!tryCreate(conf, glConf)) {
            create(conf, glConf.setSampleCount(0));
        }

        SDL_CaptureMouse(SDL_TRUE);
    }

    GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
    GL::Renderer::enable(GL::Renderer::Feature::FaceCulling);

    /* Setup the cube with vertex color */
    {
        const struct {
            Vector3 position;
            Color3 color;
        } cubeVertices[] {
            /* front */
            {{-1.0f, -1.0f,  1.0f}, 0xffff00_rgbf},
            {{ 1.0f, -1.0f,  1.0f}, 0x0000ff_rgbf},
            {{ 1.0f,  1.0f,  1.0f}, 0x000000_rgbf},
            {{-1.0f,  1.0f,  1.0f}, 0x00ff00_rgbf},

            /* back */
            {{-1.0f, -1.0f, -1.0f}, 0xffff00_rgbf},
            {{ 1.0f, -1.0f, -1.0f}, 0xffffff_rgbf},
            {{ 1.0f,  1.0f, -1.0f}, 0xff00ff_rgbf},
            {{-1.0f,  1.0f, -1.0f}, 0xff0000_rgbf}
        };

        UnsignedByte cubeIndices[]{
            /* front */
            0, 1, 2, 2, 3, 0,
            /* right */
            1, 5, 6, 6, 2, 1,
            /* back */
            7, 6, 5, 5, 4, 7,
            /* left */
            4, 0, 3, 3, 7, 4,
            /* bottom */
            4, 5, 1, 1, 0, 4,
            /* top */
            3, 2, 6, 6, 7, 3
        };

        _mesh = GL::Mesh{};
        _mesh.setCount(Containers::arraySize(cubeIndices))
            .addVertexBuffer(GL::Buffer{cubeVertices}, 0,
                Shaders::VertexColor3D::Position{},
                Shaders::VertexColor3D::Color3{})
            .setIndexBuffer(GL::Buffer{cubeIndices}, 0, MeshIndexType::UnsignedByte);

        _shader = Shaders::VertexColor3D{};
        new VertexColorDrawable{*(new Object3D{ &_scene }), _shader, _mesh, _drawables};
    }

    /* Set up the camera */
    {
        /* Setup the arcball after the camera objects */
        const Vector3 eye = Vector3::zAxis(-10.0f);
        const Vector3 center{};
        const Vector3 up = Vector3::yAxis();
        _arcballCamera.emplace(_scene, eye, center, up, 45.0_degf,
            windowSize(), framebufferSize());
    }

    /* Start the timer, loop at 60 Hz max */
    setSwapInterval(1);
    setMinimalLoopPeriod(16);
}

void ArcBallExample::drawEvent() {
    GL::defaultFramebuffer.clear(
        GL::FramebufferClear::Color|GL::FramebufferClear::Depth);

    /* Call arcball update in every frame. This will do nothing if the camera
       has not been changed. Otherwise, camera transformation will be
       propagated into the camera objects. */

    bool camChanged = _arcballCamera->update();
    _arcballCamera->draw(_drawables);
    swapBuffers();

    if(camChanged) redraw();
}

void ArcBallExample::viewportEvent(ViewportEvent& event) {
    GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()});

    _arcballCamera->reshape(event.windowSize(), event.framebufferSize());
}

void ArcBallExample::keyPressEvent(KeyEvent& event) {
    switch(event.key()) {
        case KeyEvent::Key::Plus:
        case KeyEvent::Key::NumAdd:
            _arcballCamera->zoom(1.0f);
            break;
        case KeyEvent::Key::Minus:
        case KeyEvent::Key::NumSubtract:
            _arcballCamera->zoom(-1.0f);
            break;
        case KeyEvent::Key::Left:
            _arcballCamera->translateDelta(Vector2::xAxis(-0.1f));
            break;
        case KeyEvent::Key::Right:
            _arcballCamera->translateDelta(Vector2::xAxis(0.1f));
            break;
        case KeyEvent::Key::Up:
            _arcballCamera->translateDelta(Vector2::yAxis(0.1f));
            break;
        case KeyEvent::Key::Down:
            _arcballCamera->translateDelta(Vector2::yAxis(-0.1f));
            break;

        case KeyEvent::Key::L:
            _arcballCamera->setLagging(_arcballCamera->lagging() > 0.0f ?
                0.0f : 0.85f);
            break;
        case KeyEvent::Key::R:
            _arcballCamera->reset();
            break;

        default: return;
    }

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mousePressEvent(MouseEvent& event) {
    if(event.button() != MouseEvent::Button::Left &&
       event.button() != MouseEvent::Button::Right) return;

    _arcballCamera->initTransformation(event.position());

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mouseMoveEvent(MouseMoveEvent& event) {
    if(event.buttons() & MouseMoveEvent::Button::Left)
        _arcballCamera->rotate(event.position());
    else if(event.buttons() & MouseMoveEvent::Button::Right)
        _arcballCamera->translate(event.position());
    else return;

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

void ArcBallExample::mouseScrollEvent(MouseScrollEvent& event) {
    const Float delta = event.offset().y();
    if(Math::abs(delta) < 1.0e-2f) return;

    _arcballCamera->zoom(delta);

    event.setAccepted();
    redraw(); /* camera has changed, redraw! */
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::ArcBallExample)
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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 copyright holders 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.
 *
 * Authors: Gabe Black
 *          Ali Saidi
 */

#include "arch/sparc/floatregfile.hh"
#include "base/trace.hh"
#include "sim/byteswap.hh"
#include "sim/serialize.hh"

using namespace SparcISA;
using namespace std;

class Checkpoint;

string SparcISA::getFloatRegName(RegIndex index)
{
    static std::string floatRegName[NumFloatRegs] =
        {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
         "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
         "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
         "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
         "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
         "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
    return floatRegName[index];
}

void FloatRegFile::clear()
{
    bzero(regSpace, sizeof(regSpace));
}

FloatReg FloatRegFile::readReg(int floatReg, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    switch(width)
    {
      case SingleWidth:
        float32_t result32;
        memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
        return htog(result32);
      case DoubleWidth:
        float64_t result64;
        memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
        return htog(result64);
      case QuadWidth:
        float128_t result128;
        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
        return htog(result128);
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
}

FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    switch(width)
    {
      case SingleWidth:
        uint32_t result32;
        memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
        return htog(result32);
      case DoubleWidth:
        uint64_t result64;
        memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
        return htog(result64);
      case QuadWidth:
        uint64_t result128;
        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
        return htog(result128);
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
}

Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.

    uint32_t result32;
    uint64_t result64;
    DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
    switch(width)
    {
      case SingleWidth:
        result32 = gtoh((uint32_t)val);
        memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
        break;
      case DoubleWidth:
        result64 = gtoh((uint64_t)val);
        memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
        break;
      case QuadWidth:
        panic("Quad width FP not implemented.");
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return NoFault;
}

Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    uint32_t result32;
    uint64_t result64;
    switch(width)
    {
      case SingleWidth:
        result32 = gtoh((uint32_t)val);
        memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
        break;
      case DoubleWidth:
        result64 = gtoh((uint64_t)val);
        memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
        break;
      case QuadWidth:
        panic("Quad width FP not implemented.");
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return NoFault;
}

void FloatRegFile::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY((unsigned char *)regSpace,
            SingleWidth / 8 * NumFloatRegs);
}

void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY((unsigned char *)regSpace,
            SingleWidth / 8 * NumFloatRegs);
}

<commit_msg>Fiddled with the floating point accessors.<commit_after>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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 copyright holders 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.
 *
 * Authors: Gabe Black
 *          Ali Saidi
 */

#include "arch/sparc/floatregfile.hh"
#include "base/trace.hh"
#include "sim/byteswap.hh"
#include "sim/serialize.hh"

using namespace SparcISA;
using namespace std;

class Checkpoint;

string SparcISA::getFloatRegName(RegIndex index)
{
    static std::string floatRegName[NumFloatRegs] =
        {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
         "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
         "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
         "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
         "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
         "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
    return floatRegName[index];
}

void FloatRegFile::clear()
{
    bzero(regSpace, sizeof(regSpace));
}

FloatReg FloatRegFile::readReg(int floatReg, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    FloatReg result;
    switch(width)
    {
      case SingleWidth:
        float32_t result32;
        memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
        result = htog(result32);
        break;
      case DoubleWidth:
        float64_t result64;
        memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
        result = htog(result64);
        break;
      case QuadWidth:
        float128_t result128;
        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
        result = htog(result128);
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return result;
}

FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    FloatRegBits result;
    switch(width)
    {
      case SingleWidth:
        uint32_t result32;
        memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
        result = htog(result32);
        break;
      case DoubleWidth:
        uint64_t result64;
        memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
        result = htog(result64);
        break;
      case QuadWidth:
        uint64_t result128;
        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
        result = htog(result128);
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return result;
}

Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.

    uint32_t result32;
    uint64_t result64;
    switch(width)
    {
      case SingleWidth:
        result32 = gtoh((uint32_t)val);
        memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
        break;
      case DoubleWidth:
        result64 = gtoh((uint64_t)val);
        memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
        break;
      case QuadWidth:
        panic("Quad width FP not implemented.");
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return NoFault;
}

Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
{
    //In each of these cases, we have to copy the value into a temporary
    //variable. This is because we may otherwise try to access an
    //unaligned portion of memory.
    uint32_t result32;
    uint64_t result64;
    switch(width)
    {
      case SingleWidth:
        result32 = gtoh((uint32_t)val);
        memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
        break;
      case DoubleWidth:
        result64 = gtoh((uint64_t)val);
        memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
        break;
      case QuadWidth:
        panic("Quad width FP not implemented.");
        break;
      default:
        panic("Attempted to read a %d bit floating point register!", width);
    }
    return NoFault;
}

void FloatRegFile::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY((unsigned char *)regSpace,
            SingleWidth / 8 * NumFloatRegs);
}

void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY((unsigned char *)regSpace,
            SingleWidth / 8 * NumFloatRegs);
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2013-2016 Ubidots.

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

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

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

Made by Mateo Velez - Metavix for Ubidots Inc

*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "UbidotsArduino.h"

/**
 * Constructor.
 */
Ubidots::Ubidots(char* token, char* server) {
    _token = token;
    _server = server;
    currentValue = 0;
    val = (Value *)malloc(MAX_VALUES*sizeof(Value));
}
/**
 * This function is to get value from the Ubidots API
 * @arg id the id where you will get the data
 * @return true uppon succes
 */

/**
 * This function is to get variable information from the Ubidots API
 * @arg dot is pointer to struct ubi_value
 * @return dot->value, the float value of the dot you get from the Ubidots API
 * The struct dot is updated, providing access to:
 * dot->value       := (float) value of datadot
 * dot->count       := number of datadots
 * dot->timestamp   := timestamp in SECONDS
 * dot->valid       := reading valid
 * Example Code for Arduino:
  ubi_value ubi_struct = {"575e754d76254211xxxxxxxx", 0.0, 0L, false};  // Ubidots struct for "Switch"
  float value;

  value=client.getValueInfo(&ubi_struct); // This is the important call

  if (ubi_struct.valid){  // Ubidot Value is valid
      Serial.print(" Ubi_struct: "+String(ubi_struct.value,DEC)+" Count:"+String(ubi_struct.count,DEC)+" timestamp[s]:"+String(ubi_struct.timestamp,DEC));
   } else {
     Serial.println("UBIDOTS: ERROR getDot(Dot_Switch) ");
   }
*
**/
void Ubidots::getValueInfo(ubi_value* dot) {
    String raw;
    char reply[500];
    int i = 0;
    int timeout = 3000;
    char* id = dot->id;
    uint8_t bodyPosinit;
    uint8_t bodyPosend;
    _client.connect(SERVER, PORT);
    if (_client.connected()) {
        Serial.println(F("Getting your dot"));
        // Make a HTTP request:
        _client.print(F("GET /api/v1.6/variables/"));
        _client.print(id);
        _client.println(F("/values?page_size=1 HTTP/1.1"));
        _client.println(F("Host: things.ubidots.com"));
        _client.println(F("User-Agent: Arduino-WiFi/1.0"));
        _client.print(F("X-Auth-Token: "));
        _client.println(_token);
        _client.println(F("Connection: close"));
        _client.println();
    } else {
        Serial.println(F("Connection failed"));
        dot->valid = false;
        return;
    }
    while (!_client.available()) { // Allow Timeout in endless loop
        delay(100);
        timeout -= 100;
        if (timeout < 0) {
            Serial.println(F("ERROR: Wating for client timed out"));
            break;
        }
    }
    while (_client.available()) {
        reply[i] = _client.read();
        i++;
        if(i >= 499) {
          i = 0;
          break;
        }
        //Serial.write(c);
    }
    _client.stop();
//  Serial.println(reply);
    char* pch;
    char* rest;
    dot->valid = true;
    pch = strstr(reply,"\"value\":");
    raw = String(pch);
    bodyPosinit = 9 + raw.indexOf("\"value\":");
    bodyPosend = raw.indexOf(", \"timestamp\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->value = raw.toFloat();

    bodyPosinit = 9 + raw.indexOf("\"count\": ");
    bodyPosend = raw.indexOf(", \"next\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->count = atof(raw.c_str());

    bodyPosinit = 13 + raw.indexOf("\"timestamp\": ");
    bodyPosend = raw.indexOf(", \"context\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->count = atof(raw.c_str());
    return;
}

float * Ubidots::getValue(char* id) {
    String raw;
    float arrayResponse[2];
    arrayResponse[0] = 0;
    arrayResponse[1] = 0;
    char reply[500];
    int i = 0;
    uint8_t bodyPosinit;
    uint8_t bodyPosend;
    _client.connect(_server, PORT);
    if (_client.connected()) {
        Serial.println(F("Geting your variable"));
        // Make a HTTP request:
        _client.print(F("GET /api/v1.6/variables/"));
        _client.print(id);
        _client.println(F("/values?page_size=1 HTTP/1.1"));
        _client.println(F("Host: things.ubidots.com"));
        _client.println(F("User-Agent: Arduino-WiFi/1.0"));
        _client.print(F("X-Auth-Token: "));
        _client.println(_token);
        _client.println(F("Connection: close"));
        _client.println();
    } else {
        Serial.println(F("Connection failed"));
        return arrayResponse;
    }
    int timeout = 0;
    while (!_client.available() && timeout < 5000) {
        delay(1);
        timeout++;
    }
    while (_client.available()) {
        reply[i] = _client.read();
        i++;
        if (i >= 499) {
            i = 0;
            break;
        }
    }
    _client.stop();
    arrayResponse[0] = 1;
    Serial.println(reply);
    char* pch = strstr(reply, "\"value\":");
    raw = String(pch);
    bodyPosinit = 9 + raw.indexOf("\"value\":");
    bodyPosend = raw.indexOf(", \"timestamp\"");
    raw.substring(bodyPosinit, bodyPosend).toCharArray(reply, 10);
    arrayResponse[1] = atof(reply);
    return arrayResponse;
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, float value) {
    (val+currentValue)->id = variable_id;
    (val+currentValue)->value_id = value;
    currentValue++;
    if (currentValue > MAX_VALUES) {
        Serial.println(F("You are sending more than 5 consecutives variables, you just could send 5 variables. Then other variables will be deleted!"));
        currentValue = MAX_VALUES;
    }
}
/**
 * Send all data of all variables that you saved
 * @reutrn true upon success, false upon error.
 */
bool Ubidots::sendAll() {
    String payload;
    String httpHeaders;
    String str;
    uint8_t size = 0;
    httpHeaders = "POST /api/v1.6/collections/values/?force=true HTTP/1.1\r\n";
    httpHeaders += "Host: things.ubidots.com\r\n";
    httpHeaders += "User-Agent: Arduino-WiFi/" + VERSION +"\r\n";
    httpHeaders += "X-Auth-Token: " + _token + "\r\n";
    httpHeaders += "Connection: close\r\n";
    httpHeaders += "Content-Type: application/json\r\n";
    payload = "[";
    for (int i = 0; i < currentValue; ) {
        str = String(((val+i)->value_id), 2);
        payload += "{\"variable\": \"{" + (val + i)->id +"}\", \"value\":"+ str +"}";
        i++;
        if (i < currentValue) {
            payload += ", ";
        }
    }
    payload += "]\r\n";
    size = payload.length();
    httpHeaders += "Content-Length: "+ String(size) +"\r\n\r\n";
#ifdef META_DEBUG
    Serial.println("The full HTTP is: ");
    Serial.print(httpHeaders);
    Serial.println(payload);
    httpHeaders += payload;
#endif

    if (_client.connect(_server, PORT)) {
        Serial.println(F("The TCP socket is opened"));
        _client.println(httpHeaders)
        _client.flush();
    }
    int timeout = 0;
    delay(100);
    while (!_client.available() && timeout < 5000) {
        delay(1);
        timeout++;
    }
    while (_client.available()) {
        char c = _client.read();
        Serial.write(c);
    }
    currentValue = 0;
    _client.stop();
    return true;
}
<commit_msg>deleted braces<commit_after>/*
Copyright (c) 2013-2016 Ubidots.

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

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

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

Made by Mateo Velez - Metavix for Ubidots Inc

*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "UbidotsArduino.h"

/**
 * Constructor.
 */
Ubidots::Ubidots(char* token, char* server) {
    _token = token;
    _server = server;
    currentValue = 0;
    val = (Value *)malloc(MAX_VALUES*sizeof(Value));
}
/**
 * This function is to get value from the Ubidots API
 * @arg id the id where you will get the data
 * @return true uppon succes
 */

/**
 * This function is to get variable information from the Ubidots API
 * @arg dot is pointer to struct ubi_value
 * @return dot->value, the float value of the dot you get from the Ubidots API
 * The struct dot is updated, providing access to:
 * dot->value       := (float) value of datadot
 * dot->count       := number of datadots
 * dot->timestamp   := timestamp in SECONDS
 * dot->valid       := reading valid
 * Example Code for Arduino:
  ubi_value ubi_struct = {"575e754d76254211xxxxxxxx", 0.0, 0L, false};  // Ubidots struct for "Switch"
  float value;

  value=client.getValueInfo(&ubi_struct); // This is the important call

  if (ubi_struct.valid){  // Ubidot Value is valid
      Serial.print(" Ubi_struct: "+String(ubi_struct.value,DEC)+" Count:"+String(ubi_struct.count,DEC)+" timestamp[s]:"+String(ubi_struct.timestamp,DEC));
   } else {
     Serial.println("UBIDOTS: ERROR getDot(Dot_Switch) ");
   }
*
**/
void Ubidots::getValueInfo(ubi_value* dot) {
    String raw;
    char reply[500];
    int i = 0;
    int timeout = 3000;
    char* id = dot->id;
    uint8_t bodyPosinit;
    uint8_t bodyPosend;
    _client.connect(SERVER, PORT);
    if (_client.connected()) {
        Serial.println(F("Getting your dot"));
        // Make a HTTP request:
        _client.print(F("GET /api/v1.6/variables/"));
        _client.print(id);
        _client.println(F("/values?page_size=1 HTTP/1.1"));
        _client.println(F("Host: things.ubidots.com"));
        _client.println(F("User-Agent: Arduino-WiFi/1.0"));
        _client.print(F("X-Auth-Token: "));
        _client.println(_token);
        _client.println(F("Connection: close"));
        _client.println();
    } else {
        Serial.println(F("Connection failed"));
        dot->valid = false;
        return;
    }
    while (!_client.available()) { // Allow Timeout in endless loop
        delay(100);
        timeout -= 100;
        if (timeout < 0) {
            Serial.println(F("ERROR: Wating for client timed out"));
            break;
        }
    }
    while (_client.available()) {
        reply[i] = _client.read();
        i++;
        if(i >= 499) {
          i = 0;
          break;
        }
        //Serial.write(c);
    }
    _client.stop();
//  Serial.println(reply);
    char* pch;
    char* rest;
    dot->valid = true;
    pch = strstr(reply,"\"value\":");
    raw = String(pch);
    bodyPosinit = 9 + raw.indexOf("\"value\":");
    bodyPosend = raw.indexOf(", \"timestamp\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->value = raw.toFloat();

    bodyPosinit = 9 + raw.indexOf("\"count\": ");
    bodyPosend = raw.indexOf(", \"next\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->count = atof(raw.c_str());

    bodyPosinit = 13 + raw.indexOf("\"timestamp\": ");
    bodyPosend = raw.indexOf(", \"context\"");
    raw.substring(bodyPosinit, bodyPosend);
    dot->count = atof(raw.c_str());
    return;
}

float * Ubidots::getValue(char* id) {
    String raw;
    float arrayResponse[2];
    arrayResponse[0] = 0;
    arrayResponse[1] = 0;
    char reply[500];
    int i = 0;
    uint8_t bodyPosinit;
    uint8_t bodyPosend;
    _client.connect(_server, PORT);
    if (_client.connected()) {
        Serial.println(F("Geting your variable"));
        // Make a HTTP request:
        _client.print(F("GET /api/v1.6/variables/"));
        _client.print(id);
        _client.println(F("/values?page_size=1 HTTP/1.1"));
        _client.println(F("Host: things.ubidots.com"));
        _client.println(F("User-Agent: Arduino-WiFi/1.0"));
        _client.print(F("X-Auth-Token: "));
        _client.println(_token);
        _client.println(F("Connection: close"));
        _client.println();
    } else {
        Serial.println(F("Connection failed"));
        return arrayResponse;
    }
    int timeout = 0;
    while (!_client.available() && timeout < 5000) {
        delay(1);
        timeout++;
    }
    while (_client.available()) {
        reply[i] = _client.read();
        i++;
        if (i >= 499) {
            i = 0;
            break;
        }
    }
    _client.stop();
    arrayResponse[0] = 1;
    Serial.println(reply);
    char* pch = strstr(reply, "\"value\":");
    raw = String(pch);
    bodyPosinit = 9 + raw.indexOf("\"value\":");
    bodyPosend = raw.indexOf(", \"timestamp\"");
    raw.substring(bodyPosinit, bodyPosend).toCharArray(reply, 10);
    arrayResponse[1] = atof(reply);
    return arrayResponse;
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, float value) {
    (val+currentValue)->id = variable_id;
    (val+currentValue)->value_id = value;
    currentValue++;
    if (currentValue > MAX_VALUES) {
        Serial.println(F("You are sending more than 5 consecutives variables, you just could send 5 variables. Then other variables will be deleted!"));
        currentValue = MAX_VALUES;
    }
}
/**
 * Send all data of all variables that you saved
 * @reutrn true upon success, false upon error.
 */
bool Ubidots::sendAll() {
    String payload;
    String httpHeaders;
    String str;
    uint8_t size = 0;
    httpHeaders = "POST /api/v1.6/collections/values/?force=true HTTP/1.1\r\n";
    httpHeaders += "Host: things.ubidots.com\r\n";
    httpHeaders += "User-Agent: Arduino-WiFi/" + VERSION +"\r\n";
    httpHeaders += "X-Auth-Token: " + _token + "\r\n";
    httpHeaders += "Connection: close\r\n";
    httpHeaders += "Content-Type: application/json\r\n";
    payload = "[";
    for (int i = 0; i < currentValue; ) {
        str = String(((val+i)->value_id), 2);
        payload += "{\"variable\": \"" + (val + i)->id +"\", \"value\":"+ str +"}";
        i++;
        if (i < currentValue) {
            payload += ", ";
        }
    }
    payload += "]\r\n";
    size = payload.length();
    httpHeaders += "Content-Length: "+ String(size) +"\r\n\r\n";
#ifdef META_DEBUG
    Serial.println("The full HTTP is: ");
    Serial.print(httpHeaders);
    Serial.println(payload);
    httpHeaders += payload;
#endif

    if (_client.connect(_server, PORT)) {
        Serial.println(F("The TCP socket is opened"));
        _client.println(httpHeaders)
        _client.flush();
    }
    int timeout = 0;
    delay(100);
    while (!_client.available() && timeout < 5000) {
        delay(1);
        timeout++;
    }
    while (_client.available()) {
        char c = _client.read();
        Serial.write(c);
    }
    currentValue = 0;
    _client.stop();
    return true;
}
<|endoftext|>


<commit_before>#pragma once

#include <agency/detail/config.hpp>
#include <agency/future.hpp>
#include <agency/new_executor_traits.hpp>
#include <agency/detail/executor_traits/shared_parameter_container.hpp>
#include <agency/detail/executor_traits/check_for_member_functions.hpp>
#include <agency/detail/index_cast.hpp>
#include <type_traits>
#include <utility>
#include <cassert>

namespace agency
{
namespace detail
{
namespace new_executor_traits_detail
{

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(std::true_type, Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  return ex.template when_all_execute_and_select<Indices...>(f, shape, std::forward<TupleOfFutures>(futures), std::forward<Types>(shared_inits)...);
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

template<class Function, class Shape>
struct multi_agent_when_all_execute_and_select_with_shared_inits_functor
{
  mutable Function f;
  Shape shape;

  template<size_t depth, class AgentIndex>
  __AGENCY_ANNOTATION
  size_t rank_in_group(const AgentIndex& idx) const
  {
    // to compute the rank of an index at a particular depth,
    // first prepend 0 (1) to idx (shape) to represent an index of the root group (it has none otherwise)
    // XXX seems like index_cast() should just do the right thing for empty indices
    //     it would correspond to a single-agent task
    auto augmented_idx   = detail::tuple_prepend(detail::wrap_scalar(idx), size_t{0});
    auto augmented_shape = detail::tuple_prepend(detail::wrap_scalar(shape), size_t{1});

    // take the first depth+1 (plus one because we prepended 1) indices of the index & shape and do an index_cast to size_t
    return detail::index_cast<size_t>(detail::tuple_take<depth+1>(augmented_idx),
                                      detail::tuple_take<depth+1>(augmented_shape),
                                      detail::shape_size(detail::tuple_take<depth+1>(augmented_shape)));
  }

  template<size_t... ContainerIndices, class AgentIndex, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<ContainerIndices...>, AgentIndex&& agent_idx, TupleOfContainers&& shared_arg_containers, Types&... past_args) const
  {
    f(std::forward<AgentIndex>(agent_idx),                                                             // pass the agent index
      past_args...,                                                                                // pass the arguments coming in from futures
      std::get<ContainerIndices>(shared_arg_containers)[rank_in_group<ContainerIndices>(agent_idx)]... // pass the arguments coming in from shared parameters
    );
  }

  template<class Index, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void operator()(Index&& idx, TupleOfContainers& shared_arg_containers, Types&... past_args) const
  {
    static const size_t num_containers = std::tuple_size<TupleOfContainers>::value;
    impl(detail::make_index_sequence<num_containers>(), std::forward<Index>(idx), shared_arg_containers, past_args...);
  }
};

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(std::false_type, Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  // create a tuple of containers holding a shared parameter for each group
  auto shared_param_containers_tuple = new_executor_traits_detail::make_tuple_of_shared_parameter_containers(ex, shape, std::forward<Types>(shared_inits)...);

  // turn it into a future
  auto shared_param_containers_tuple_fut = new_executor_traits<Executor>::template make_ready_future<decltype(shared_param_containers_tuple)>(ex, std::move(shared_param_containers_tuple));

  // combine the shared parameters with the incoming futures
  // the tuple of containers goes in front of the incoming futures
  auto shared_and_futures = detail::tuple_prepend(std::move(futures), std::move(shared_param_containers_tuple_fut));

  // wrap f with a functor to map container elements to shared parameters
  auto g = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, typename new_executor_traits<Executor>::shape_type>{f, shape};

  // add one to the indices to skip the tuple of containers which was prepended to the tuple of futures
  return new_executor_traits<Executor>::template when_all_execute_and_select<(Indices+1)...>(ex, g, shape, std::move(shared_and_futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

} // end detail
} // end new_executor_traits_detail

template<class Executor>
template<size_t... Indices, class Function, class TupleOfFutures, class T1, class... Types>
  typename new_executor_traits<Executor>::template future<
    detail::when_all_execute_and_select_result_t<
      detail::index_sequence<Indices...>,
      typename std::decay<TupleOfFutures>::type
    >
  >
  new_executor_traits<Executor>
    ::when_all_execute_and_select(typename new_executor_traits<Executor>::executor_type& ex,
                                  Function f,
                                  typename new_executor_traits<Executor>::shape_type shape,
                                  TupleOfFutures&& futures,
                                  T1&& outer_shared_init,
                                  Types&&... inner_shared_inits)
{
  static_assert(new_executor_traits<Executor>::execution_depth == 1 + sizeof...(Types), "The number of shared initializers must be equal to the executor's execution_depth.");

  using check_for_member_function = detail::new_executor_traits_detail::has_multi_agent_when_all_execute_and_select_with_shared_inits<
    detail::index_sequence<Indices...>,
    Executor,
    Function,
    typename std::decay<TupleOfFutures>::type,
    detail::type_list<T1,Types...>
  >;

  return detail::new_executor_traits_detail::multi_agent_when_all_execute_and_select_with_shared_inits<Indices...>(check_for_member_function(), ex, f, shape, std::forward<TupleOfFutures>(futures), std::forward<T1>(outer_shared_init), std::forward<Types>(inner_shared_inits)...);
} // end new_executor_traits::when_all_execute_and_select()

} // end agency

<commit_msg>Implement multi-agent when_all_execute_and_select() with shared inits with single-agent when_all_execute_and_select() with nested multi-agent execute() with shared inits<commit_after>#pragma once

#include <agency/detail/config.hpp>
#include <agency/future.hpp>
#include <agency/new_executor_traits.hpp>
#include <agency/detail/executor_traits/shared_parameter_container.hpp>
#include <agency/detail/executor_traits/check_for_member_functions.hpp>
#include <agency/detail/index_cast.hpp>
#include <type_traits>
#include <utility>
#include <cassert>

namespace agency
{
namespace detail
{
namespace new_executor_traits_detail
{
namespace multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
{

struct use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function {};

struct use_multi_agent_when_all_execute_and_select_member_function {};

struct use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits {};

template<class Function, class Shape>
struct multi_agent_when_all_execute_and_select_with_shared_inits_functor
{
  mutable Function f;
  Shape shape;

  template<size_t depth, class AgentIndex>
  __AGENCY_ANNOTATION
  size_t rank_in_group(const AgentIndex& idx) const
  {
    // to compute the rank of an index at a particular depth,
    // first prepend 0 (1) to idx (shape) to represent an index of the root group (it has none otherwise)
    // XXX seems like index_cast() should just do the right thing for empty indices
    //     it would correspond to a single-agent task
    auto augmented_idx   = detail::tuple_prepend(detail::wrap_scalar(idx), size_t{0});
    auto augmented_shape = detail::tuple_prepend(detail::wrap_scalar(shape), size_t{1});

    // take the first depth+1 (plus one because we prepended 1) indices of the index & shape and do an index_cast to size_t
    return detail::index_cast<size_t>(detail::tuple_take<depth+1>(augmented_idx),
                                      detail::tuple_take<depth+1>(augmented_shape),
                                      detail::shape_size(detail::tuple_take<depth+1>(augmented_shape)));
  }

  template<size_t... ContainerIndices, class AgentIndex, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<ContainerIndices...>, AgentIndex&& agent_idx, TupleOfContainers&& shared_arg_containers, Types&... past_args) const
  {
    f(std::forward<AgentIndex>(agent_idx),                                                             // pass the agent index
      past_args...,                                                                                // pass the arguments coming in from futures
      std::get<ContainerIndices>(shared_arg_containers)[rank_in_group<ContainerIndices>(agent_idx)]... // pass the arguments coming in from shared parameters
    );
  }

  template<class Index, class TupleOfContainers, class... Types>
  __AGENCY_ANNOTATION
  void operator()(Index&& idx, TupleOfContainers& shared_arg_containers, Types&... past_args) const
  {
    static const size_t num_containers = std::tuple_size<TupleOfContainers>::value;
    impl(detail::make_index_sequence<num_containers>(), std::forward<Index>(idx), shared_arg_containers, past_args...);
  }
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
struct has_multi_agent_when_all_execute_and_select_member_function_impl;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
struct has_multi_agent_when_all_execute_and_select_member_function_impl<detail::index_sequence<Indices...>,Executor,Function,TupleOfFutures,detail::type_list<Types...>>
{
  using tuple_of_shared_parameter_containers_type = tuple_of_shared_parameter_containers<Executor, typename std::decay<Types>::type...>;

  using future_tuple_of_shared_parameter_containers_type = typename new_executor_traits<Executor>::template future<tuple_of_shared_parameter_containers_type>;

  using prepended_tuple_of_futures_type = tuple_prepend_result_t<TupleOfFutures, future_tuple_of_shared_parameter_containers_type>;

  using shape_type = typename new_executor_traits<Executor>::shape_type;

  using wrapped_function_type = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, shape_type>;

  using type = typename new_executor_traits_detail::has_multi_agent_when_all_execute_and_select<
    Executor, wrapped_function_type, prepended_tuple_of_futures_type, (Indices+1)...
  >::type;
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
struct select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<
  detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
>
{
  using type = typename std::conditional<
    has_multi_agent_when_all_execute_and_select_with_shared_inits<
      detail::index_sequence<Indices...>, Executor, Function, TupleOfFutures, type_list<Types...>
    >::value,
    use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
    typename std::conditional<
      has_multi_agent_when_all_execute_and_select<Executor, Function, TupleOfFutures, Indices...>::value,
      use_multi_agent_when_all_execute_and_select_member_function,
      use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits
    >::type
  >::type;
};

template<class IndexSequence, class Executor, class Function, class TupleOfFutures, class TypeList>
using select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation = typename select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation_impl<IndexSequence,Executor,Function,TupleOfFutures,TypeList>::type;

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_with_shared_inits_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  return ex.template when_all_execute_and_select<Indices...>(f, shape, std::forward<TupleOfFutures>(futures), std::forward<Types>(shared_inits)...);
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_multi_agent_when_all_execute_and_select_member_function,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  // create a tuple of containers holding a shared parameter for each group
  auto shared_param_containers_tuple = new_executor_traits_detail::make_tuple_of_shared_parameter_containers(ex, shape, std::forward<Types>(shared_inits)...);

  // turn it into a future
  auto shared_param_containers_tuple_fut = new_executor_traits<Executor>::template make_ready_future<decltype(shared_param_containers_tuple)>(ex, std::move(shared_param_containers_tuple));

  // combine the shared parameters with the incoming futures
  // the tuple of containers goes in front of the incoming futures
  auto shared_and_futures = detail::tuple_prepend(std::move(futures), std::move(shared_param_containers_tuple_fut));

  // wrap f with a functor to map container elements to shared parameters
  auto g = multi_agent_when_all_execute_and_select_with_shared_inits_functor<Function, typename new_executor_traits<Executor>::shape_type>{f, shape};

  // add one to the indices to skip the tuple of containers which was prepended to the tuple of futures
  return ex.template when_all_execute_and_select<(Indices+1)...>(g, shape, std::move(shared_and_futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

// this functor is passed to single-agent when_all_execute_and_select below
// it makes a nested call to terminal multi-agent execute()
template<class Executor, class Function, class... Types>
struct terminal_execute_with_shared_inits_functor
{
  Executor& ex;
  mutable Function f;
  typename new_executor_traits<Executor>::shape_type shape;
  detail::tuple<Types...> shared_inits;

  // this is the functor we pass to new_executor_traits::execute() below
  template<class... FutureValueTypes>
  struct nested_functor
  {
    mutable Function f;
    mutable detail::tuple<FutureValueTypes&...> args_from_futures;

    template<size_t... TupleIndices, class Index, class... Args>
    __AGENCY_ANNOTATION
    void impl(detail::index_sequence<TupleIndices...>, const Index& idx, Args&... shared_args) const
    {
      // XXX should use std::invoke()
      f(idx, std::get<TupleIndices>(args_from_futures)..., shared_args...);
    }

    template<class Index, class... Args>
    __AGENCY_ANNOTATION
    void operator()(const Index& idx, Args&... shared_args) const
    {
      impl(detail::make_index_sequence<sizeof...(FutureValueTypes)>(), idx, shared_args...);
    }
  };

  template<size_t... TupleIndices, class... Args>
  __AGENCY_ANNOTATION
  void impl(detail::index_sequence<TupleIndices...>, Args&... future_args) const
  {
    //// XXX with polymorphic lambda we'd write something like this:
    //new_executor_traits<Executor>::execute(ex, [=,&args...](const auto& idx, auto&... shared_args)
    //{
    //  // XXX should use std::invoke()
    //  f(idx, args..., shared_args...);
    //},
    //shape,
    //std::get<Indices>(shared_inits)...
    //);

    auto g = nested_functor<Args...>{f, detail::tie(future_args...)};

    new_executor_traits<Executor>::execute(ex, g, shape, std::get<TupleIndices>(shared_inits)...);
  }

  template<class... Args>
  __AGENCY_ANNOTATION
  void operator()(Args&... future_args) const
  {
    impl(detail::make_index_sequence<sizeof...(Types)>(), future_args...);
  }
};

template<size_t... Indices, class Executor, class Function, class TupleOfFutures, class... Types>
typename new_executor_traits<Executor>::template future<
  detail::when_all_execute_and_select_result_t<
    detail::index_sequence<Indices...>,
    typename std::decay<TupleOfFutures>::type
  >
>
  multi_agent_when_all_execute_and_select_with_shared_inits(use_single_agent_when_all_execute_and_select_with_nested_terminal_multi_agent_execute_with_shared_inits,
                                                            Executor& ex, Function f, typename new_executor_traits<Executor>::shape_type shape, TupleOfFutures&& futures, Types&&... shared_inits)
{
  // XXX with polymorphic lambda we'd write something like this:
  //return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, [=,&ex](auto&... args)
  //{
  //  new_executor_traits<Executor>::execute(ex, [=,&args](const auto& idx)
  //  {
  //    f(idx, args...);
  //  },
  //  shape,
  //  shared_inits...);
  //},
  //std::forward<TupleOfFutures>(futures),
  //std::forward<Types>(shared_inits)...
  //);

  using functor_type = terminal_execute_with_shared_inits_functor<Executor,Function,typename std::decay<Types>::type...>;
  functor_type g{ex, f, shape, detail::make_tuple(std::forward<Types>(shared_inits)...)};

  return new_executor_traits<Executor>::template when_all_execute_and_select<Indices...>(ex, g, std::forward<TupleOfFutures>(futures));
} // end multi_agent_when_all_execute_and_select_with_shared_inits()

} // end multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies
} // end detail
} // end new_executor_traits_detail

template<class Executor>
template<size_t... Indices, class Function, class TupleOfFutures, class T1, class... Types>
  typename new_executor_traits<Executor>::template future<
    detail::when_all_execute_and_select_result_t<
      detail::index_sequence<Indices...>,
      typename std::decay<TupleOfFutures>::type
    >
  >
  new_executor_traits<Executor>
    ::when_all_execute_and_select(typename new_executor_traits<Executor>::executor_type& ex,
                                  Function f,
                                  typename new_executor_traits<Executor>::shape_type shape,
                                  TupleOfFutures&& futures,
                                  T1&& outer_shared_init,
                                  Types&&... inner_shared_inits)
{
  static_assert(new_executor_traits<Executor>::execution_depth == 1 + sizeof...(Types), "The number of shared initializers must be equal to the executor's execution_depth.");

  namespace ns = detail::new_executor_traits_detail::multi_agent_when_all_execute_and_select_with_shared_inits_implementation_strategies;

  using implementation_strategy = ns::select_multi_agent_when_all_execute_and_select_with_shared_inits_implementation<
    detail::index_sequence<Indices...>,
    Executor,
    Function,
    typename std::decay<TupleOfFutures>::type,
    detail::type_list<T1,Types...>
  >;

  return ns::multi_agent_when_all_execute_and_select_with_shared_inits<Indices...>(implementation_strategy(), ex, f, shape, std::forward<TupleOfFutures>(futures), std::forward<T1>(outer_shared_init), std::forward<Types>(inner_shared_inits)...);
} // end new_executor_traits::when_all_execute_and_select()

} // end agency

<|endoftext|>


<commit_before>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
#include "../cPWP/calcPWP.h"
#include "catch.hpp"
#include <string>
#include <iostream>
#include <fstream>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(1000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
}

TEST_CASE( "Generate sequence reads", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 1, 100, 300, "normalRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef_R1.fastq", "normalRef_R2.fastq", "normal.bam", "25") == 0);
}

/*
TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 1, 100, 300, "mutatedRef") == 0);
}

TEST_CASE( " Mapping second set of reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "mutatedRef_R1.fastq", "mutatedRef_R2.fastq", "mutated.bam", "25") == 0);
}
*/

TEST_CASE( "Create heterozygous R1", "[createHet]") {
    REQUIRE( createHeterozygousGenome("normalRef_R1.fastq", "mutatedRef_R1.fastq", "hetRef_R1.fastq") == 0);
}

TEST_CASE( "Create heterozygous R2", "[createHet]") {
    REQUIRE( createHeterozygousGenome("normalRef_R2.fastq", "mutatedRef_R2.fastq", "hetRef_R2.fastq") == 0);
}

TEST_CASE( " Mapping het reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "hetRef_R1.fastq", "hetRef_R2.fastq", "het.bam", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

/*

TEST_CASE( "Generate mutated reference genomes and simulate reads", "[genomeAndReadSim]") {
    REQUIRE( generateReadsAndMap(3, 0.01, "300", "25", "10000", "100", "1234", "simulatedReferenceGenome.fasta", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

 */

TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 5000) == 0); // 5000 as a max because we don't want to exclude any loci for this test
}

TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile ("angsdOut.readCounts.binary", 0, 2, "testingOut.pwp", 30) == 0);
}

<commit_msg>Minor changes<commit_after>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
#include "../cPWP/calcPWP.h"
#include "catch.hpp"
#include <string>
#include <iostream>
#include <fstream>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(1000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
}

TEST_CASE( "Generate sequence reads", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 1, 100, 300, "normalRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef_R1.fastq", "normalRef_R2.fastq", "normal.bam", "25") == 0);
}

/*
TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 1, 100, 300, "mutatedRef") == 0);
}

*/

TEST_CASE( " Mapping second set of reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "mutatedRef_R1.fastq", "mutatedRef_R2.fastq", "mutated.bam", "25") == 0);
}

TEST_CASE( "Create heterozygous R1", "[createHet]") {
    REQUIRE( createHeterozygousGenome("normalRef_R1.fastq", "mutatedRef_R1.fastq", "hetRef_R1.fastq") == 0);
}

TEST_CASE( "Create heterozygous R2", "[createHet]") {
    REQUIRE( createHeterozygousGenome("normalRef_R2.fastq", "mutatedRef_R2.fastq", "hetRef_R2.fastq") == 0);
}

TEST_CASE( " Mapping het reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "hetRef_R1.fastq", "hetRef_R2.fastq", "het.bam", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

/*

TEST_CASE( "Generate mutated reference genomes and simulate reads", "[genomeAndReadSim]") {
    REQUIRE( generateReadsAndMap(3, 0.01, "300", "25", "10000", "100", "1234", "simulatedReferenceGenome.fasta", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

 */

TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 5000) == 0); // 5000 as a max because we don't want to exclude any loci for this test
}

TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile ("angsdOut.readCounts.binary", 0, 2, "testingOut.pwp", 30) == 0);
}

<|endoftext|>