<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2018.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://www.opensource.org/licenses/MIT)
//=======================================================================

#ifndef VECTOR_H
#define VECTOR_H

#include <initializer_list.hpp>
#include <types.hpp>
#include <algorithms.hpp>
#include <new.hpp>
#include <iterator.hpp>

namespace std {

/*!
 * \brief A contiguous container of elements, automatically increasing.
 */
template<typename T>
struct vector {
    using value_type           = T;                 ///< The value type contained in the vector
    using pointer_type         = value_type*;       ///< The pointer type contained in the vector
    using reference_type       = value_type&;       ///< The pointer type contained in the vector
    using const_reference_type = const value_type&; ///< The pointer type contained in the vector
    using size_type            = size_t;            ///< The size type
    using iterator             = value_type*;       ///< The iterator type
    using const_iterator       = const value_type*; ///< The const iterator type

    using reverse_iterator       = std::reverse_iterator<iterator>;       ///< The reverse iterator type
    using const_reverse_iterator = std::reverse_iterator<const_iterator>; ///< The const reverse iterator type

    /*!
     * \brief Constructs en empty vector
     */
    vector() : _data(nullptr), _size(0), _capacity(0) {}

    /*!
     * \brief Constructs a vector of the given size
     */
    explicit vector(uint64_t c) : _data(allocate(c)), _size(0), _capacity(c) {}

    /*!
     * \brief Construct a vector containing the given values
     */
    vector(initializer_list<T> values) : _data(allocate(values.size())), _size(values.size()), _capacity(values.size()) {
        size_t i = 0;
        for(auto& v : values){
            new (&_data[i++]) value_type(v);
        }
    }

    vector(const vector& rhs) : _data(nullptr), _size(rhs._size), _capacity(rhs._capacity) {
        if(!rhs.empty()){
            _data = allocate(_capacity);

            for(size_t i = 0; i < _size; ++i){
                new (&_data[i]) value_type(rhs._data[i]);
            }
        }
    }

    vector& operator=(const vector& rhs){
        if (this != &rhs) {
            if (_capacity < rhs._capacity) {
                if (_data) {
                    release();
                }

                _capacity = rhs._capacity;
                _data      = allocate(_capacity);
            } else {
                destruct_all();
            }

            _size = rhs._size;

            for (size_t i = 0; i < _size; ++i) {
                new (&_data[i]) value_type(rhs._data[i]);
            }
        }

        return *this;
    }

    //Move constructors

    vector(vector&& rhs) : _data(rhs._data), _size(rhs._size), _capacity(rhs._capacity) {
        rhs._data = nullptr;
        rhs._size = 0;
        rhs._capacity = 0;
    };

    vector& operator=(vector&& rhs){
        if (this != &rhs) {
            if (_data) {
                release();
            }

            _data          = rhs._data;
            _size         = rhs._size;
            _capacity     = rhs._capacity;

            rhs._data      = nullptr;
            rhs._size     = 0;
            rhs._capacity = 0;
        }

        return *this;
    }

    ~vector(){
        if(_data){
            release();
        }
    }

    //Getters

    /*!
     * \brief Returns the size of the vector
     */
    constexpr size_type size() const noexcept {
        return _size;
    }

    /*!
     * \brief Indicates if the vector is empty
     */
    bool empty() const noexcept {
        return _size == 0;
    }

    /*!
     * \brief Returns the capacity of the vector
     */
    constexpr size_type capacity() const noexcept {
        return _capacity;
    }

    /*!
     * \brief Returns a pointer to the underlying array.
     */
    value_type* data() noexcept {
        return _data;
    }

    /*!
     * \brief Returns a pointer to the underlying array.
     */
    const value_type* data() const noexcept {
        return _data;
    }

    /*!
     * \brief Returns a const reference to the elemenet at the given position
     */
    constexpr const value_type& operator[](size_type pos) const {
        return _data[pos];
    }

    /*!
     * \brief Returns a reference to the elemenet at the given position
     */
    value_type& operator[](size_type pos){
        return _data[pos];
    }

    /*!
     * \brief Returns a reference to the element at the front of the collection
     */
    value_type& front(){
        return _data[0];
    }

    /*!
     * \brief Returns a const reference to the element at the front of the collection
     */
    const value_type& front() const  {
        return _data[0];
    }

    /*!
     * \brief Returns a reference to the element at the back of the collection
     */
    value_type& back(){
        return _data[size() - 1];
    }

    /*!
     * \brief Returns a const reference to the element at the back of the collection
     */
    const value_type& back() const  {
        return _data[size() - 1];
    }

    //Modifiers

    /*!
     * \brief Augments the capacity to at least the given capacity
     */
    void reserve(size_t new_capacity){
        if(new_capacity > capacity()){
            ensure_capacity(new_capacity);
        }
    }

    /*!
     * \brief Resize the vector to the given size
     */
    void resize(size_t new_size){
        if(new_size > size()){
            ensure_capacity(new_size);

            // Default initialize the new elements
            for(size_t i = _size; i < new_size; ++i){
                new (&_data[i]) value_type();
            }

            _size = new_size;
        } else if(new_size < _size){
            // Call the necessary destructors
            for(size_t i = new_size; i < _size; ++i){
                _data[i].~value_type();
            }

            //By diminishing the size, the last elements become unreachable
            _size = new_size;
        }
    }

    /*!
     * \brief Add an element at the back of the vector
     */
    void push_back(value_type&& element){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type(std::move(element));
    }

    /*!
     * \brief Add an element at the back of the vector
     */
    void push_back(const value_type& element){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type(element);
    }

    /*!
     * \brief Construct a new element inplace
     */
    value_type& emplace_back(){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type();

        return back();
    }

    /*!
     * \brief Construct a new element inplace
     */
    template<typename... Args>
    value_type& emplace_back(Args... args){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type{std::forward<Args>(args)...};

        return back();
    }

    /*!
     * \brief Add an element at the front of the vector
     */
    void push_front(value_type&& element){
        ensure_capacity(_size + 1);

        if(!empty()){
            new (&_data[_size]) value_type(std::move(_data[_size - 1]));

            for (size_t i = _size - 1; i > 0; --i) {
                _data[i] = std::move(_data[i - 1]);
            }
        }

        // At this point _data[0] has been deleted
        _data[0] = std::move(element);

        ++_size;
    }

    /*!
     * \brief Add an element at the front of the vector
     */
    void push_front(const value_type& element){
        ensure_capacity(_size + 1);

        if(!empty()){
            new (&_data[_size]) value_type(std::move(_data[_size - 1]));

            for (size_t i = _size - 1; i > 0; --i) {
                _data[i] = std::move(_data[i - 1]);
            }
        }

        // At this point _data[0] has been deleted
        _data[0] = element;

        ++_size;
    }

    /*!
     * \brief Removes the last element of the vector
     */
    void pop_back(){
        --_size;

        // Call the destructor of the erased value
        _data[_size].~value_type();
    }

    /*!
     * \brief Removes all the elements of the vector
     */
    void clear(){
        destruct_all();

        _size = 0;
    }

    /*!
     * \brief Erase the element at the given position
     */
    void erase(size_t position){
        for(size_t i = position; i < _size - 1; ++i){
            _data[i] = std::move(_data[i+1]);
        }

        --_size;

        // Call the destructor of the last value
        _data[_size].~value_type();
    }

    /*!
     * \brief Erase the element at the given position
     */
    void erase(iterator position){
        for(size_t i = position - begin(); i < _size - 1; ++i){
            _data[i] = std::move(_data[i+1]);
        }

        --_size;

        // Call the destructor of the last value
        _data[_size].~value_type();
    }

    /*!
     * \brief Erase all the elements of the given range
     */
    void erase(iterator first, iterator last){
        auto n = std::distance(first, last);

        for(size_t i = first - begin(); i < _size - n; ++i){
            _data[i] = std::move(_data[i+n]);
        }

        // Call the destructors on the erase elements
        for(size_t i = _size - n; i < _size; ++i){
            _data[i].~value_type();
        }

        _size -= n;
    }

    //Iterators

    /*!
     * \brief Return an iterator to point to the first element
     */
    iterator begin(){
        return iterator(&_data[0]);
    }

    /*!
     * \brief Return an iterator to point to the first element
     */
    constexpr const_iterator begin() const {
        return const_iterator(&_data[0]);
    }

    /*!
     * \brief Return an iterator to point to the past-the-end element
     */
    iterator end(){
        return iterator(&_data[_size]);
    }

    /*!
     * \brief Return an iterator to point to the past-the-end element
     */
    constexpr const_iterator end() const {
        return const_iterator(&_data[_size]);
    }

    //Iterators

    /*!
     * \brief Return a reverse iterator to point to the first element
     */
    reverse_iterator rbegin(){
        return reverse_iterator(&_data[int64_t(_size) - 1]);
    }

    /*!
     * \brief Return a reverse iterator to point to the first element
     */
    constexpr const_reverse_iterator rbegin() const {
        return const_iterator(&_data[int64_t(_size) - 1]);
    }

    /*!
     * \brief Return a reverse iterator point to the past-the-end element
     */
    reverse_iterator rend(){
        return reverse_iterator(&_data[-1]);
    }

    /*!
     * \brief Return a reverse iterator point to the past-the-end element
     */
    constexpr const_reverse_iterator rend() const {
        return const_reverse_iterator(&_data[-1]);
    }

    // Relational operators

    bool operator==(const vector& rhs) const {
        if(size() != rhs.size()){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != rhs[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const vector& rhs) const {
        return !(*this == rhs);
    }

private:
    static value_type* allocate(size_t n){
        return reinterpret_cast<value_type*>(new uint8_t[n * sizeof(value_type)]);
    }

    static void deallocate(value_type* ptr){
        delete[] reinterpret_cast<uint8_t*>(ptr);
    }

    void destruct_all(){
        // Call the destructors
        for(size_t i = 0; i< _size; ++i){
            _data[i].~value_type();
        }
    }

    void release(){
        destruct_all();

        // Deallocate the memory
        deallocate(_data);
        _data = nullptr;
    }

    void ensure_capacity(size_t new_capacity){
        if(_capacity == 0){
            _capacity = new_capacity;
            _data = allocate(_capacity);
        } else if(_capacity < new_capacity){
            // Double the current capacity
            _capacity= _capacity * 2;

            // If not enough, use the given new_capacity
            if(new_capacity > _capacity){
                _capacity = new_capacity;
            }

            auto new_data = allocate(_capacity);

            // Move the old _data into the new one
            for(size_t i = 0; i < _size; ++i){
                new (&new_data[i]) value_type(std::move(_data[i]));
            }

            release();

            _data = new_data;
        }
    }

    T* _data; ///< The data storage
    uint64_t _size; ///< The vector size
    uint64_t _capacity; ///< The data capacity
};

} //end of namespace std

#endif
<commit_msg>Clean comment<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2018.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://www.opensource.org/licenses/MIT)
//=======================================================================

#ifndef VECTOR_H
#define VECTOR_H

#include <initializer_list.hpp>
#include <types.hpp>
#include <algorithms.hpp>
#include <new.hpp>
#include <iterator.hpp>

namespace std {

/*!
 * \brief A contiguous container of elements, automatically increasing.
 */
template<typename T>
struct vector {
    using value_type           = T;                 ///< The value type contained in the vector
    using pointer_type         = value_type*;       ///< The pointer type contained in the vector
    using reference_type       = value_type&;       ///< The pointer type contained in the vector
    using const_reference_type = const value_type&; ///< The pointer type contained in the vector
    using size_type            = size_t;            ///< The size type
    using iterator             = value_type*;       ///< The iterator type
    using const_iterator       = const value_type*; ///< The const iterator type

    using reverse_iterator       = std::reverse_iterator<iterator>;       ///< The reverse iterator type
    using const_reverse_iterator = std::reverse_iterator<const_iterator>; ///< The const reverse iterator type

    /*!
     * \brief Constructs en empty vector
     */
    vector() : _data(nullptr), _size(0), _capacity(0) {}

    /*!
     * \brief Constructs a vector of the given size
     */
    explicit vector(uint64_t c) : _data(allocate(c)), _size(0), _capacity(c) {}

    /*!
     * \brief Construct a vector containing the given values
     */
    vector(initializer_list<T> values) : _data(allocate(values.size())), _size(values.size()), _capacity(values.size()) {
        size_t i = 0;
        for(auto& v : values){
            new (&_data[i++]) value_type(v);
        }
    }

    vector(const vector& rhs) : _data(nullptr), _size(rhs._size), _capacity(rhs._capacity) {
        if(!rhs.empty()){
            _data = allocate(_capacity);

            for(size_t i = 0; i < _size; ++i){
                new (&_data[i]) value_type(rhs._data[i]);
            }
        }
    }

    vector& operator=(const vector& rhs){
        if (this != &rhs) {
            if (_capacity < rhs._capacity) {
                if (_data) {
                    release();
                }

                _capacity = rhs._capacity;
                _data      = allocate(_capacity);
            } else {
                destruct_all();
            }

            _size = rhs._size;

            for (size_t i = 0; i < _size; ++i) {
                new (&_data[i]) value_type(rhs._data[i]);
            }
        }

        return *this;
    }

    //Move constructors

    vector(vector&& rhs) : _data(rhs._data), _size(rhs._size), _capacity(rhs._capacity) {
        rhs._data = nullptr;
        rhs._size = 0;
        rhs._capacity = 0;
    };

    vector& operator=(vector&& rhs){
        if (this != &rhs) {
            if (_data) {
                release();
            }

            _data          = rhs._data;
            _size         = rhs._size;
            _capacity     = rhs._capacity;

            rhs._data      = nullptr;
            rhs._size     = 0;
            rhs._capacity = 0;
        }

        return *this;
    }

    ~vector(){
        if(_data){
            release();
        }
    }

    //Getters

    /*!
     * \brief Returns the size of the vector
     */
    constexpr size_type size() const noexcept {
        return _size;
    }

    /*!
     * \brief Indicates if the vector is empty
     */
    bool empty() const noexcept {
        return _size == 0;
    }

    /*!
     * \brief Returns the capacity of the vector
     */
    constexpr size_type capacity() const noexcept {
        return _capacity;
    }

    /*!
     * \brief Returns a pointer to the underlying array.
     */
    value_type* data() noexcept {
        return _data;
    }

    /*!
     * \brief Returns a pointer to the underlying array.
     */
    const value_type* data() const noexcept {
        return _data;
    }

    /*!
     * \brief Returns a const reference to the elemenet at the given position
     */
    constexpr const value_type& operator[](size_type pos) const {
        return _data[pos];
    }

    /*!
     * \brief Returns a reference to the elemenet at the given position
     */
    value_type& operator[](size_type pos){
        return _data[pos];
    }

    /*!
     * \brief Returns a reference to the element at the front of the collection
     */
    value_type& front(){
        return _data[0];
    }

    /*!
     * \brief Returns a const reference to the element at the front of the collection
     */
    const value_type& front() const  {
        return _data[0];
    }

    /*!
     * \brief Returns a reference to the element at the back of the collection
     */
    value_type& back(){
        return _data[size() - 1];
    }

    /*!
     * \brief Returns a const reference to the element at the back of the collection
     */
    const value_type& back() const  {
        return _data[size() - 1];
    }

    //Modifiers

    /*!
     * \brief Augments the capacity to at least the given capacity
     */
    void reserve(size_t new_capacity){
        if(new_capacity > capacity()){
            ensure_capacity(new_capacity);
        }
    }

    /*!
     * \brief Resize the vector to the given size
     */
    void resize(size_t new_size){
        if(new_size > size()){
            ensure_capacity(new_size);

            // Default initialize the new elements
            for(size_t i = _size; i < new_size; ++i){
                new (&_data[i]) value_type();
            }

            _size = new_size;
        } else if(new_size < _size){
            // Call the necessary destructors
            for(size_t i = new_size; i < _size; ++i){
                _data[i].~value_type();
            }

            //By diminishing the size, the last elements become unreachable
            _size = new_size;
        }
    }

    /*!
     * \brief Add an element at the back of the vector
     */
    void push_back(value_type&& element){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type(std::move(element));
    }

    /*!
     * \brief Add an element at the back of the vector
     */
    void push_back(const value_type& element){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type(element);
    }

    /*!
     * \brief Construct a new element inplace
     */
    value_type& emplace_back(){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type();

        return back();
    }

    /*!
     * \brief Construct a new element inplace
     */
    template<typename... Args>
    value_type& emplace_back(Args... args){
        ensure_capacity(_size + 1);

        new (&_data[_size++]) value_type{std::forward<Args>(args)...};

        return back();
    }

    /*!
     * \brief Add an element at the front of the vector
     */
    void push_front(value_type&& element){
        ensure_capacity(_size + 1);

        if(!empty()){
            new (&_data[_size]) value_type(std::move(_data[_size - 1]));

            for (size_t i = _size - 1; i > 0; --i) {
                _data[i] = std::move(_data[i - 1]);
            }
        }

        // At this point _data[0] has been deleted
        _data[0] = std::move(element);

        ++_size;
    }

    /*!
     * \brief Add an element at the front of the vector
     */
    void push_front(const value_type& element){
        ensure_capacity(_size + 1);

        if(!empty()){
            new (&_data[_size]) value_type(std::move(_data[_size - 1]));

            for (size_t i = _size - 1; i > 0; --i) {
                _data[i] = std::move(_data[i - 1]);
            }
        }

        // At this point _data[0] has been deleted
        _data[0] = element;

        ++_size;
    }

    /*!
     * \brief Removes the last element of the vector
     */
    void pop_back(){
        --_size;

        // Call the destructor of the erased value
        _data[_size].~value_type();
    }

    /*!
     * \brief Removes all the elements of the vector
     */
    void clear(){
        destruct_all();

        _size = 0;
    }

    /*!
     * \brief Erase the element at the given position
     */
    void erase(size_t position){
        for(size_t i = position; i < _size - 1; ++i){
            _data[i] = std::move(_data[i+1]);
        }

        --_size;

        // Call the destructor of the last value
        _data[_size].~value_type();
    }

    /*!
     * \brief Erase the element at the given position
     */
    void erase(iterator position){
        for(size_t i = position - begin(); i < _size - 1; ++i){
            _data[i] = std::move(_data[i+1]);
        }

        --_size;

        // Call the destructor of the last value
        _data[_size].~value_type();
    }

    /*!
     * \brief Erase all the elements of the given range
     */
    void erase(iterator first, iterator last){
        auto n = std::distance(first, last);

        for(size_t i = first - begin(); i < _size - n; ++i){
            _data[i] = std::move(_data[i+n]);
        }

        // Call the destructors on the erase elements
        for(size_t i = _size - n; i < _size; ++i){
            _data[i].~value_type();
        }

        _size -= n;
    }

    //Iterators

    /*!
     * \brief Return an iterator to point to the first element
     */
    iterator begin(){
        return iterator(&_data[0]);
    }

    /*!
     * \brief Return an iterator to point to the first element
     */
    constexpr const_iterator begin() const {
        return const_iterator(&_data[0]);
    }

    /*!
     * \brief Return an iterator to point to the past-the-end element
     */
    iterator end(){
        return iterator(&_data[_size]);
    }

    /*!
     * \brief Return an iterator to point to the past-the-end element
     */
    constexpr const_iterator end() const {
        return const_iterator(&_data[_size]);
    }

    // Reverse Iterators

    /*!
     * \brief Return a reverse iterator to point to the first element
     */
    reverse_iterator rbegin(){
        return reverse_iterator(&_data[int64_t(_size) - 1]);
    }

    /*!
     * \brief Return a reverse iterator to point to the first element
     */
    constexpr const_reverse_iterator rbegin() const {
        return const_iterator(&_data[int64_t(_size) - 1]);
    }

    /*!
     * \brief Return a reverse iterator point to the past-the-end element
     */
    reverse_iterator rend(){
        return reverse_iterator(&_data[-1]);
    }

    /*!
     * \brief Return a reverse iterator point to the past-the-end element
     */
    constexpr const_reverse_iterator rend() const {
        return const_reverse_iterator(&_data[-1]);
    }

    // Relational operators

    bool operator==(const vector& rhs) const {
        if(size() != rhs.size()){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != rhs[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const vector& rhs) const {
        return !(*this == rhs);
    }

private:
    static value_type* allocate(size_t n){
        return reinterpret_cast<value_type*>(new uint8_t[n * sizeof(value_type)]);
    }

    static void deallocate(value_type* ptr){
        delete[] reinterpret_cast<uint8_t*>(ptr);
    }

    void destruct_all(){
        // Call the destructors
        for(size_t i = 0; i< _size; ++i){
            _data[i].~value_type();
        }
    }

    void release(){
        destruct_all();

        // Deallocate the memory
        deallocate(_data);
        _data = nullptr;
    }

    void ensure_capacity(size_t new_capacity){
        if(_capacity == 0){
            _capacity = new_capacity;
            _data = allocate(_capacity);
        } else if(_capacity < new_capacity){
            // Double the current capacity
            _capacity= _capacity * 2;

            // If not enough, use the given new_capacity
            if(new_capacity > _capacity){
                _capacity = new_capacity;
            }

            auto new_data = allocate(_capacity);

            // Move the old _data into the new one
            for(size_t i = 0; i < _size; ++i){
                new (&new_data[i]) value_type(std::move(_data[i]));
            }

            release();

            _data = new_data;
        }
    }

    T* _data; ///< The data storage
    uint64_t _size; ///< The vector size
    uint64_t _capacity; ///< The data capacity
};

} //end of namespace std

#endif
<|endoftext|>


<commit_before>#include <compilerdata.h>

void rootlogon(){
   gSystem->AddIncludePath(RINCLUDEPATH);
   gSystem->AddLinkedLibs(RLINKEDLIBS);
}
<commit_msg>Remove it because it is not needed anymore<commit_after><|endoftext|>


<commit_before>#include "APIClient.h"

#include <cxxabi.h>
#include <rapidjson/error/en.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>
#include <sstream>
#include <string>

#include "Status.h"

namespace rustla2 {

namespace {

template <typename T>
std::string GetDemangledClassName(T* ptr) {
  int status;
  char* name = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
  return std::string("memes");
}

}  // namespace

Status APIResult::Validate(const rapidjson::Document& data) {
  auto schema = GetSchema();
  if (schema.HasParseError()) {
    return Status(StatusCode::JSON_SCHEMA_ERROR,
                  "invalid json schema in " + GetDemangledClassName(this),
                  rapidjson::GetParseError_En(schema.GetParseError()));
  }

  auto schema_doc = rapidjson::SchemaDocument(schema);
  rapidjson::SchemaValidator validator(schema_doc);

  if (data_.HasParseError()) {
    return Status(StatusCode::JSON_PARSE_ERROR,
                  "invalid json response in " + GetDemangledClassName(this),
                  rapidjson::GetParseError_En(data_.GetParseError()));
  }
  if (!data_.Accept(validator)) {
    rapidjson::StringBuffer doc_uri;
    rapidjson::StringBuffer schema_uri;
    validator.GetInvalidDocumentPointer().StringifyUriFragment(doc_uri);
    validator.GetInvalidSchemaPointer().StringifyUriFragment(schema_uri);

    std::stringstream error_details;
    error_details << "invalid " << validator.GetInvalidSchemaKeyword() << ", "
                  << "document at " << doc_uri.GetString() << " "
                  << "does not match schema at " << schema_uri.GetString();

    return Status(StatusCode::VALIDATION_ERROR, "json validation failed",
                  error_details.str());
  }

  return Status::OK;
}

Status APIResult::SetData(const char* data, size_t length) {
  data_.Parse(data, length);
  return Validate(data_);
}

}  // namespace rustla2
<commit_msg>revert test<commit_after>#include "APIClient.h"

#include <cxxabi.h>
#include <rapidjson/error/en.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>
#include <sstream>
#include <string>

#include "Status.h"

namespace rustla2 {

namespace {

template <typename T>
std::string GetDemangledClassName(T* ptr) {
  int status;
  char* name = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
  return std::string(name);
}

}  // namespace

Status APIResult::Validate(const rapidjson::Document& data) {
  auto schema = GetSchema();
  if (schema.HasParseError()) {
    return Status(StatusCode::JSON_SCHEMA_ERROR,
                  "invalid json schema in " + GetDemangledClassName(this),
                  rapidjson::GetParseError_En(schema.GetParseError()));
  }

  auto schema_doc = rapidjson::SchemaDocument(schema);
  rapidjson::SchemaValidator validator(schema_doc);

  if (data_.HasParseError()) {
    return Status(StatusCode::JSON_PARSE_ERROR,
                  "invalid json response in " + GetDemangledClassName(this),
                  rapidjson::GetParseError_En(data_.GetParseError()));
  }
  if (!data_.Accept(validator)) {
    rapidjson::StringBuffer doc_uri;
    rapidjson::StringBuffer schema_uri;
    validator.GetInvalidDocumentPointer().StringifyUriFragment(doc_uri);
    validator.GetInvalidSchemaPointer().StringifyUriFragment(schema_uri);

    std::stringstream error_details;
    error_details << "invalid " << validator.GetInvalidSchemaKeyword() << ", "
                  << "document at " << doc_uri.GetString() << " "
                  << "does not match schema at " << schema_uri.GetString();

    return Status(StatusCode::VALIDATION_ERROR, "json validation failed",
                  error_details.str());
  }

  return Status::OK;
}

Status APIResult::SetData(const char* data, size_t length) {
  data_.Parse(data, length);
  return Validate(data_);
}

}  // namespace rustla2
<|endoftext|>


<commit_before>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "app.h"
#include "progressbar.h"
#include "image/voxel.h"
#include "math/matrix.h"
#include "math/eigen.h"
#include "dwi/tensor.h"

using namespace MR;

SET_VERSION_DEFAULT;
SET_AUTHOR (NULL);
SET_COPYRIGHT (NULL);

DESCRIPTION = {
  "generate maps of tensor-derived parameters.",
  NULL
};

ARGUMENTS = {
  Argument ("tensor", "the input diffusion tensor image.").type_image_in (),
  Argument ()
};

const char* modulate_choices[] = { "none", "fa", "eval", NULL };

OPTIONS = {
  Option ("adc",
      "compute the mean apparent diffusion coefficient (ADC) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("fa",
      "compute the fractional anisotropy of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("num",
      "specify the desired eigenvalue/eigenvector(s). Note that several eigenvalues "
      "can be specified as a number sequence. For example, '1,3' specifies the "
      "major (1) and minor (3) eigenvalues/eigenvectors (default = 1).")
    + Argument ("image"),

  Option ("vector",
      "compute the selected eigenvector(s) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("value",
      "compute the selected eigenvalue(s) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("mask",
      "only perform computation within the specified binary brain mask image.")
    + Argument ("image").type_image_in(),

  Option ("modulate",
      "specify how to modulate the magnitude of the eigenvectors. Valid choices "
      "are: none, FA, eval (default = FA).")
    + Argument ("spec").type_choice (modulate_choices),

  Option ()
};

class ImagePair
{
  public:
    class Header : public Image::Header {
      public:
        Header (const Image::Header& header, const std::string& name, size_t nvols) :
          Image::Header (header) {
            set_datatype (DataType::Float32);
            if (nvols) set_dim (3, nvols);
            else set_ndim (3);
            create (name);
          }

        Header (const std::string& name) : Image::Header (name) { }
    };

    ImagePair (const Image::Header& header, const std::string& name, size_t nvols) :
      H (header, name, nvols), vox (H) { }

    ImagePair (const std::string& name) : H (name), vox (H) { }

    Header H;
    Image::Voxel<float> vox;
};

inline void set_zero (size_t axis, Ptr<ImagePair>& i0, Ptr<ImagePair>& i1, Ptr<ImagePair>& i2, Ptr<ImagePair>& i3, Ptr<ImagePair>& i4)
{
  if (i0) i0->vox[axis] = 0;
  if (i1) i1->vox[axis] = 0;
  if (i2) i2->vox[axis] = 0;
  if (i3) i3->vox[axis] = 0;
  if (i4) i4->vox[axis] = 0;
}

inline void increment (size_t axis, Ptr<ImagePair>& i0, Ptr<ImagePair>& i1, Ptr<ImagePair>& i2, Ptr<ImagePair>& i3, Ptr<ImagePair>& i4)
{
  if (i0) ++i0->vox[axis];
  if (i1) ++i1->vox[axis];
  if (i2) ++i2->vox[axis];
  if (i3) ++i3->vox[axis];
  if (i4) ++i4->vox[axis];
}

EXECUTE {
  Image::Header dt_header (argument[0]);

  if (dt_header.ndim() != 4)
    throw Exception ("base image should contain 4 dimensions");

  if (dt_header.dim(3) != 6)
    throw Exception ("expecting dimension 3 of image \"" + dt_header.name() + "\" to be 6");

  std::vector<int> vals(1);
  vals[0] = 1;
  Options opt = get_options ("num");
  if (opt.size()) {
    vals = parse_ints (opt[0][0]);

    if (vals.empty())
      throw Exception ("invalid eigenvalue/eigenvector number specifier");

    for (size_t i = 0; i < vals.size(); ++i)
      if (vals[i] < 1 || vals[i] > 3)
        throw Exception ("eigenvalue/eigenvector number is out of bounds");
  }

  Ptr<ImagePair> adc, fa, eval, evec, mask;

  opt = get_options ("vector");
  if (opt.size())
    evec = new ImagePair (dt_header, opt[0][0], 3*vals.size());

  opt = get_options ("value");
  if (opt.size())
    eval = new ImagePair (dt_header, opt[0][0], vals.size());

  opt = get_options ("adc");
  if (opt.size())
    adc = new ImagePair (dt_header, opt[0][0], 3);

  opt = get_options ("fa");
  if (opt.size()) fa = new ImagePair (dt_header, opt[0][0], 0);

  opt = get_options ("mask");
  if (opt.size()) {
    mask = new ImagePair (opt[0][0]);
    if (mask->H.dim(0) != dt_header.dim(0) ||
        mask->H.dim(1) != dt_header.dim(1) ||
        mask->H.dim(2) != dt_header.dim(2))
      throw Exception ("dimensions of mask image do not match that of tensor image - aborting");
  }

  int modulate = 1;
  opt = get_options ("modulate");
  if (opt.size())
    modulate = to<int> (opt[0][0]);

  if ( ! (adc || fa || eval || evec))
    throw Exception ("no output metric specified - aborting");

  for (size_t i = 0; i < vals.size(); i++)
    vals[i] = 3-vals[i];

  Math::Matrix<double> V(3,3), M(3,3);
  Math::Vector<double> ev(3);
  float el[6], faval = NAN;

  Ptr<Math::Eigen::Symm<double> > eig;
  Ptr<Math::Eigen::SymmV<double> > eigv;
  if (evec)
    eigv = new Math::Eigen::SymmV<double> (3);
  else
    eig = new Math::Eigen::Symm<double> (3);

  Image::Voxel<float> dt (dt_header);

  ProgressBar progress ("computing tensor metrics...", DataSet::voxel_count (dt, 0, 3));

  for (dt[2] = 0; dt[2] < dt.dim(2); dt[2]++) {
    set_zero (1, mask, fa, adc, eval, evec);

    for (dt[1] = 0; dt[1] < dt.dim(1); dt[1]++) {
      set_zero (0, mask, fa, adc, eval, evec);

      for (dt[0] = 0; dt[0] < dt.dim(0); dt[0]++) {

        bool skip = false;
        if (mask) if (mask->vox.value() < 0.5) skip = true;

        if (!skip) {

          for (dt[3] = 0; dt[3] < dt.dim(3); dt[3]++)
            el[dt[3]] = dt.value();

          if (adc) adc->vox.value() = DWI::tensor2ADC (el);
          if (fa || modulate == 1) faval = DWI::tensor2FA (el);
          if (fa) fa->vox.value() = faval;

          if (eval || evec) {
            M(0,0) = el[0];
            M(1,1) = el[1];
            M(2,2) = el[2];
            M(0,1) = M(1,0) = el[3];
            M(0,2) = M(2,0) = el[4];
            M(1,2) = M(2,1) = el[5];

            if (evec) {
              (*eigv) (ev, M, V);
              Math::Eigen::sort (ev, V);
              if (modulate == 0) faval = 1.0;
              evec->vox[3] = 0;
              for (size_t i = 0; i < vals.size(); i++) {
                if (modulate == 2) faval = ev[vals[i]];
                evec->vox.value() = faval*V(0,vals[i]); ++evec->vox[3];
                evec->vox.value() = faval*V(1,vals[i]); ++evec->vox[3];
                evec->vox.value() = faval*V(2,vals[i]); ++evec->vox[3];
              }
            }
            else {
              (*eig) (ev, M);
              Math::Eigen::sort (ev);
            }

            if (eval) {
              for (eval->vox[3] = 0; eval->vox[3] < (int) vals.size(); ++eval->vox[3])
                eval->vox.value() = ev[vals[eval->vox[3]]];
            }
          }
        }

        ++progress;
        increment (0, mask, fa, adc, eval, evec);
      }
      increment (1, mask, fa, adc, eval, evec);
    }
    increment (2, mask, fa, adc, eval, evec);
  }
}

<commit_msg>minor fix to tensor_metric when handling ADC maps<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "app.h"
#include "progressbar.h"
#include "image/voxel.h"
#include "math/matrix.h"
#include "math/eigen.h"
#include "dwi/tensor.h"

using namespace MR;

SET_VERSION_DEFAULT;
SET_AUTHOR (NULL);
SET_COPYRIGHT (NULL);

DESCRIPTION = {
  "generate maps of tensor-derived parameters.",
  NULL
};

ARGUMENTS = {
  Argument ("tensor", "the input diffusion tensor image.").type_image_in (),
  Argument ()
};

const char* modulate_choices[] = { "none", "fa", "eval", NULL };

OPTIONS = {
  Option ("adc",
      "compute the mean apparent diffusion coefficient (ADC) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("fa",
      "compute the fractional anisotropy of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("num",
      "specify the desired eigenvalue/eigenvector(s). Note that several eigenvalues "
      "can be specified as a number sequence. For example, '1,3' specifies the "
      "major (1) and minor (3) eigenvalues/eigenvectors (default = 1).")
    + Argument ("image"),

  Option ("vector",
      "compute the selected eigenvector(s) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("value",
      "compute the selected eigenvalue(s) of the diffusion tensor.")
    + Argument ("image").type_image_out(),

  Option ("mask",
      "only perform computation within the specified binary brain mask image.")
    + Argument ("image").type_image_in(),

  Option ("modulate",
      "specify how to modulate the magnitude of the eigenvectors. Valid choices "
      "are: none, FA, eval (default = FA).")
    + Argument ("spec").type_choice (modulate_choices),

  Option ()
};

class ImagePair
{
  public:
    class Header : public Image::Header {
      public:
        Header (const Image::Header& header, const std::string& name, size_t nvols) :
          Image::Header (header) {
            set_datatype (DataType::Float32);
            if (nvols) set_dim (3, nvols);
            else set_ndim (3);
            create (name);
          }

        Header (const std::string& name) : Image::Header (name) { }
    };

    ImagePair (const Image::Header& header, const std::string& name, size_t nvols) :
      H (header, name, nvols), vox (H) { }

    ImagePair (const std::string& name) : H (name), vox (H) { }

    Header H;
    Image::Voxel<float> vox;
};

inline void set_zero (size_t axis, Ptr<ImagePair>& i0, Ptr<ImagePair>& i1, Ptr<ImagePair>& i2, Ptr<ImagePair>& i3, Ptr<ImagePair>& i4)
{
  if (i0) i0->vox[axis] = 0;
  if (i1) i1->vox[axis] = 0;
  if (i2) i2->vox[axis] = 0;
  if (i3) i3->vox[axis] = 0;
  if (i4) i4->vox[axis] = 0;
}

inline void increment (size_t axis, Ptr<ImagePair>& i0, Ptr<ImagePair>& i1, Ptr<ImagePair>& i2, Ptr<ImagePair>& i3, Ptr<ImagePair>& i4)
{
  if (i0) ++i0->vox[axis];
  if (i1) ++i1->vox[axis];
  if (i2) ++i2->vox[axis];
  if (i3) ++i3->vox[axis];
  if (i4) ++i4->vox[axis];
}

EXECUTE {
  Image::Header dt_header (argument[0]);

  if (dt_header.ndim() != 4)
    throw Exception ("base image should contain 4 dimensions");

  if (dt_header.dim(3) != 6)
    throw Exception ("expecting dimension 3 of image \"" + dt_header.name() + "\" to be 6");

  std::vector<int> vals(1);
  vals[0] = 1;
  Options opt = get_options ("num");
  if (opt.size()) {
    vals = parse_ints (opt[0][0]);

    if (vals.empty())
      throw Exception ("invalid eigenvalue/eigenvector number specifier");

    for (size_t i = 0; i < vals.size(); ++i)
      if (vals[i] < 1 || vals[i] > 3)
        throw Exception ("eigenvalue/eigenvector number is out of bounds");
  }

  Ptr<ImagePair> adc, fa, eval, evec, mask;

  opt = get_options ("vector");
  if (opt.size())
    evec = new ImagePair (dt_header, opt[0][0], 3*vals.size());

  opt = get_options ("value");
  if (opt.size())
    eval = new ImagePair (dt_header, opt[0][0], vals.size());

  opt = get_options ("adc");
  if (opt.size())
    adc = new ImagePair (dt_header, opt[0][0], 0);

  opt = get_options ("fa");
  if (opt.size()) fa = new ImagePair (dt_header, opt[0][0], 0);

  opt = get_options ("mask");
  if (opt.size()) {
    mask = new ImagePair (opt[0][0]);
    if (mask->H.dim(0) != dt_header.dim(0) ||
        mask->H.dim(1) != dt_header.dim(1) ||
        mask->H.dim(2) != dt_header.dim(2))
      throw Exception ("dimensions of mask image do not match that of tensor image - aborting");
  }

  int modulate = 1;
  opt = get_options ("modulate");
  if (opt.size())
    modulate = to<int> (opt[0][0]);

  if ( ! (adc || fa || eval || evec))
    throw Exception ("no output metric specified - aborting");

  for (size_t i = 0; i < vals.size(); i++)
    vals[i] = 3-vals[i];

  Math::Matrix<double> V(3,3), M(3,3);
  Math::Vector<double> ev(3);
  float el[6], faval = NAN;

  Ptr<Math::Eigen::Symm<double> > eig;
  Ptr<Math::Eigen::SymmV<double> > eigv;
  if (evec)
    eigv = new Math::Eigen::SymmV<double> (3);
  else
    eig = new Math::Eigen::Symm<double> (3);

  Image::Voxel<float> dt (dt_header);

  ProgressBar progress ("computing tensor metrics...", DataSet::voxel_count (dt, 0, 3));

  for (dt[2] = 0; dt[2] < dt.dim(2); dt[2]++) {
    set_zero (1, mask, fa, adc, eval, evec);

    for (dt[1] = 0; dt[1] < dt.dim(1); dt[1]++) {
      set_zero (0, mask, fa, adc, eval, evec);

      for (dt[0] = 0; dt[0] < dt.dim(0); dt[0]++) {

        bool skip = false;
        if (mask) if (mask->vox.value() < 0.5) skip = true;

        if (!skip) {

          for (dt[3] = 0; dt[3] < dt.dim(3); dt[3]++)
            el[dt[3]] = dt.value();

          if (adc) adc->vox.value() = DWI::tensor2ADC (el);
          if (fa || modulate == 1) faval = DWI::tensor2FA (el);
          if (fa) fa->vox.value() = faval;

          if (eval || evec) {
            M(0,0) = el[0];
            M(1,1) = el[1];
            M(2,2) = el[2];
            M(0,1) = M(1,0) = el[3];
            M(0,2) = M(2,0) = el[4];
            M(1,2) = M(2,1) = el[5];

            if (evec) {
              (*eigv) (ev, M, V);
              Math::Eigen::sort (ev, V);
              if (modulate == 0) faval = 1.0;
              evec->vox[3] = 0;
              for (size_t i = 0; i < vals.size(); i++) {
                if (modulate == 2) faval = ev[vals[i]];
                evec->vox.value() = faval*V(0,vals[i]); ++evec->vox[3];
                evec->vox.value() = faval*V(1,vals[i]); ++evec->vox[3];
                evec->vox.value() = faval*V(2,vals[i]); ++evec->vox[3];
              }
            }
            else {
              (*eig) (ev, M);
              Math::Eigen::sort (ev);
            }

            if (eval) {
              for (eval->vox[3] = 0; eval->vox[3] < (int) vals.size(); ++eval->vox[3])
                eval->vox.value() = ev[vals[eval->vox[3]]];
            }
          }
        }

        ++progress;
        increment (0, mask, fa, adc, eval, evec);
      }
      increment (1, mask, fa, adc, eval, evec);
    }
    increment (2, mask, fa, adc, eval, evec);
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 midnightBITS
 *
 * 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.
 */

#include "pch.h"
#include <log.hpp>
#include <boost/date_time.hpp>
#include <boost/filesystem.hpp>
#include <utils.hpp>
#include <clocale>
#include <locale>
#include <vector>
#include <threads.hpp>
#include <mutex>

namespace fs = boost::filesystem;

namespace Log
{
	Module Module::HTTP("HOST");
	Module Module::SSDP("SSDP");
	Module Module::UPnP("UPnP");

	template <class Elem, class Traits>
	std::basic_ostream<Elem, Traits>& operator << (std::basic_ostream<Elem, Traits>& o, Severity sev)
	{
		switch (sev)
		{
		case Severity::Debug:   return o << "DBG";
		case Severity::Info:    return o << "INF";
		case Severity::Warning: return o << "WRN";
		case Severity::Error:   return o << "ERR";
		}
		throw std::runtime_error("Severity value " + std::to_string((int)sev) + " unknown");
	}

	struct sink
	{
		static void log(const std::string& pre, const std::string& msg);
		static void log(const std::string& pre, const std::wstring& msg);
	};

	namespace detail
	{
		std::string make_prefix(Severity sev, const Module& mod)
		{
			std::ostringstream o;
			o << net::to_iso8601(net::time::now()) << " " << mod << "/" << sev << " [" << threads::get_name() << "] ";
			return o.str();
		}
		void init_stream(line_stream& s, Severity sev, const Module& mod)
		{
			s.prefix = std::move(make_prefix(sev, mod));
			s.reset_state();
		}
		void finalize_stream(line_stream& s)
		{
			if (s.has_written())
				sink::log(s.prefix, s.str());
		}
		void init_stream(line_wstream& s, Severity sev, const Module& mod)
		{
			s.prefix = std::move(make_prefix(sev, mod));
			s.reset_state();
		}
		void finalize_stream(line_wstream& s)
		{
			if (s.has_written())
				sink::log(s.prefix, s.str());
		}
	}

	void sink::log(const std::string& pre, const std::string& msg)
	{
		static std::mutex sink_mtx;
		std::lock_guard<std::mutex> lock(sink_mtx);

		std::ofstream out("libnet.log", std::ios::app | std::ios::out);

		const char* c = msg.c_str();
		const char* e = c + msg.length();

		bool line_start = true;
		while (true)
		{
			auto save = c;
			while (c != e && *c != '\n' && *c != '\r') ++c;

			if (line_start)
				out << pre;

			out.write(save, c - save);

			line_start = c == e || *c == '\n';
			if (line_start)
				out << "\n";

			if (c == e) break;
			++c;
		}
	}

	void sink::log(const std::string& pre, const std::wstring& wmsg)
	{
		std::setlocale(LC_ALL, "");
		const std::locale locale("");
		typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;

		const auto& converter = std::use_facet<converter_type>(locale);

		std::vector<char> data(wmsg.length() * converter.max_length());
		std::mbstate_t state;
		const wchar_t* from_next;
		char* to_next;

		auto result = converter.out(state, wmsg.data(), wmsg.data() + wmsg.length(), from_next, &data[0], &data[0] + data.size(), to_next);

		if (result == converter_type::ok || result == converter_type::noconv) {
			log(pre, std::string(data.data(), to_next));
		}
	}
}
<commit_msg>libenv /W4 change<commit_after>/*
 * Copyright (C) 2013 midnightBITS
 *
 * 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.
 */

#include "pch.h"
#include <log.hpp>
#include <boost/date_time.hpp>
#include <boost/filesystem.hpp>
#include <utils.hpp>
#include <clocale>
#include <locale>
#include <vector>
#include <threads.hpp>
#include <mutex>

namespace fs = boost::filesystem;

namespace Log
{
	Module Module::HTTP("HOST");
	Module Module::SSDP("SSDP");
	Module Module::UPnP("UPnP");

	template <class Elem, class Traits>
	std::basic_ostream<Elem, Traits>& operator << (std::basic_ostream<Elem, Traits>& o, Severity sev)
	{
		switch (sev)
		{
		case Severity::Debug:   return o << "DBG";
		case Severity::Info:    return o << "INF";
		case Severity::Warning: return o << "WRN";
		case Severity::Error:   return o << "ERR";
		}
		throw std::runtime_error("Severity value " + std::to_string((int)sev) + " unknown");
	}

	struct sink
	{
		static void log(const std::string& pre, const std::string& msg);
		static void log(const std::string& pre, const std::wstring& msg);
	};

	namespace detail
	{
		std::string make_prefix(Severity sev, const Module& mod)
		{
			std::ostringstream o;
			o << net::to_iso8601(net::time::now()) << " " << mod << "/" << sev << " [" << threads::get_name() << "] ";
			return o.str();
		}
		void init_stream(line_stream& s, Severity sev, const Module& mod)
		{
			s.prefix = std::move(make_prefix(sev, mod));
			s.reset_state();
		}
		void finalize_stream(line_stream& s)
		{
			if (s.has_written())
				sink::log(s.prefix, s.str());
		}
		void init_stream(line_wstream& s, Severity sev, const Module& mod)
		{
			s.prefix = std::move(make_prefix(sev, mod));
			s.reset_state();
		}
		void finalize_stream(line_wstream& s)
		{
			if (s.has_written())
				sink::log(s.prefix, s.str());
		}
	}

	void sink::log(const std::string& pre, const std::string& msg)
	{
		static std::mutex sink_mtx;
		std::lock_guard<std::mutex> lock(sink_mtx);

		std::ofstream out("libnet.log", std::ios::app | std::ios::out);

		const char* c = msg.c_str();
		const char* e = c + msg.length();

		bool line_start = true;
		for (;;)
		{
			auto save = c;
			while (c != e && *c != '\n' && *c != '\r') ++c;

			if (line_start)
				out << pre;

			out.write(save, c - save);

			line_start = c == e || *c == '\n';
			if (line_start)
				out << "\n";

			if (c == e) break;
			++c;
		}
	}

	void sink::log(const std::string& pre, const std::wstring& wmsg)
	{
		std::setlocale(LC_ALL, "");
		const std::locale locale("");
		typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;

		const auto& converter = std::use_facet<converter_type>(locale);

		std::vector<char> data(wmsg.length() * converter.max_length());
		std::mbstate_t state;
		const wchar_t* from_next;
		char* to_next;

		auto result = converter.out(state, wmsg.data(), wmsg.data() + wmsg.length(), from_next, &data[0], &data[0] + data.size(), to_next);

		if (result == converter_type::ok || result == converter_type::noconv) {
			log(pre, std::string(data.data(), to_next));
		}
	}
}
<|endoftext|>


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

#include <pcl/pcl_config.h>
#ifdef HAVE_OPENNI

#include <pcl/io/pcd_grabber.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>

//////////////////////// GrabberImplementation //////////////////////
struct pcl::PCDGrabberBase::PCDGrabberImpl
{
  PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat);
  PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat);
  void trigger ();
  void readAhead ();
  pcl::PCDGrabberBase& grabber_;
  float frames_per_second_;
  bool repeat_;
  bool running_;
  std::vector<std::string> pcd_files_;
  std::vector<std::string>::iterator pcd_iterator_;
  TimeTrigger time_trigger_;

  sensor_msgs::PointCloud2 next_cloud_;
  bool valid_;
};

pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat)
: grabber_ (grabber)
, frames_per_second_ (frames_per_second)
, repeat_ (repeat)
, running_ (false)
, time_trigger_ (1.0 / (double) std::max(frames_per_second, 0.001f), boost::bind (&PCDGrabberImpl::trigger, this))
, valid_ (false)
{
  pcd_files_.push_back (pcd_path);
  pcd_iterator_ = pcd_files_.begin ();
}

pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
: grabber_ (grabber)
, frames_per_second_ (frames_per_second)
, repeat_ (repeat)
, running_ (false)
, time_trigger_ (1.0 / (double) std::max(frames_per_second, 0.001f), boost::bind (&PCDGrabberImpl::trigger, this))
, valid_ (false)
{
  pcd_files_ = pcd_files;
  pcd_iterator_ = pcd_files_.begin ();
}

void pcl::PCDGrabberBase::PCDGrabberImpl::readAhead ()
{
  if (pcd_iterator_ != pcd_files_.end ())
  {
    PCDReader reader;
    int pcd_version;
    Eigen::Vector4f origin;
    Eigen::Quaternionf orientation;
    valid_ = (reader.read (*pcd_iterator_, next_cloud_, origin, orientation, pcd_version) == 0);

    if (++pcd_iterator_ == pcd_files_.end () && repeat_)
      pcd_iterator_ = pcd_files_.begin ();
  }
  else
    valid_ = false;
}

void pcl::PCDGrabberBase::PCDGrabberImpl::trigger ()
{
  if (valid_)
    grabber_.publish (next_cloud_);

  // use remaining time, if there is time left!
  readAhead ();
}

//////////////////////// GrabberBase //////////////////////
pcl::PCDGrabberBase::PCDGrabberBase (const std::string& pcd_path, float frames_per_second, bool repeat)
: impl_( new PCDGrabberImpl (*this, pcd_path, frames_per_second, repeat ) )
{
}

pcl::PCDGrabberBase::PCDGrabberBase (const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
: impl_( new PCDGrabberImpl (*this, pcd_files, frames_per_second, repeat) )
{
}

pcl::PCDGrabberBase::~PCDGrabberBase () throw ()
{
  stop ();
  delete impl_;
}

void pcl::PCDGrabberBase::start ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->running_ = true;
    impl_->time_trigger_.start ();
  }
  else // manual trigger
  {
    impl_->trigger ();
  }
}

void pcl::PCDGrabberBase::stop ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->time_trigger_.stop ();
    impl_->running_ = false;
  }
}

bool pcl::PCDGrabberBase::isRunning () const
{
  return impl_->running_;
}

std::string pcl::PCDGrabberBase::getName () const
{
  return "PCDGrabber";
}

void pcl::PCDGrabberBase::rewind ()
{
  impl_->pcd_iterator_ = impl_->pcd_files_.begin ();
}

float pcl::PCDGrabberBase::getFramesPerSecond () const
{
  return impl_->frames_per_second_;
}

bool pcl::PCDGrabberBase::isRepeatOn () const
{
  return impl_->repeat_;
}
#endif
<commit_msg>removed OPENNI ifdefs<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. 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.
 *
 */

#include <pcl/pcl_config.h>
#include <pcl/io/pcd_grabber.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>

///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// GrabberImplementation //////////////////////
struct pcl::PCDGrabberBase::PCDGrabberImpl
{
  PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat);
  PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat);
  void trigger ();
  void readAhead ();
  pcl::PCDGrabberBase& grabber_;
  float frames_per_second_;
  bool repeat_;
  bool running_;
  std::vector<std::string> pcd_files_;
  std::vector<std::string>::iterator pcd_iterator_;
  TimeTrigger time_trigger_;

  sensor_msgs::PointCloud2 next_cloud_;
  bool valid_;
};

///////////////////////////////////////////////////////////////////////////////////////////
pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat)
: grabber_ (grabber)
, frames_per_second_ (frames_per_second)
, repeat_ (repeat)
, running_ (false)
, time_trigger_ (1.0 / (double) std::max(frames_per_second, 0.001f), boost::bind (&PCDGrabberImpl::trigger, this))
, valid_ (false)
{
  pcd_files_.push_back (pcd_path);
  pcd_iterator_ = pcd_files_.begin ();
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
: grabber_ (grabber)
, frames_per_second_ (frames_per_second)
, repeat_ (repeat)
, running_ (false)
, time_trigger_ (1.0 / (double) std::max(frames_per_second, 0.001f), boost::bind (&PCDGrabberImpl::trigger, this))
, valid_ (false)
{
  pcd_files_ = pcd_files;
  pcd_iterator_ = pcd_files_.begin ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCDGrabberBase::PCDGrabberImpl::readAhead ()
{
  if (pcd_iterator_ != pcd_files_.end ())
  {
    PCDReader reader;
    int pcd_version;
    Eigen::Vector4f origin;
    Eigen::Quaternionf orientation;
    valid_ = (reader.read (*pcd_iterator_, next_cloud_, origin, orientation, pcd_version) == 0);

    if (++pcd_iterator_ == pcd_files_.end () && repeat_)
      pcd_iterator_ = pcd_files_.begin ();
  }
  else
    valid_ = false;
}

void
pcl::PCDGrabberBase::PCDGrabberImpl::trigger ()
{
  if (valid_)
    grabber_.publish (next_cloud_);

  // use remaining time, if there is time left!
  readAhead ();
}

///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// GrabberBase //////////////////////
pcl::PCDGrabberBase::PCDGrabberBase (const std::string& pcd_path, float frames_per_second, bool repeat)
: impl_( new PCDGrabberImpl (*this, pcd_path, frames_per_second, repeat ) )
{
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::PCDGrabberBase::PCDGrabberBase (const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
: impl_( new PCDGrabberImpl (*this, pcd_files, frames_per_second, repeat) )
{
}

///////////////////////////////////////////////////////////////////////////////////////////
pcl::PCDGrabberBase::~PCDGrabberBase () throw ()
{
  stop ();
  delete impl_;
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCDGrabberBase::start ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->running_ = true;
    impl_->time_trigger_.start ();
  }
  else // manual trigger
    impl_->trigger ();
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCDGrabberBase::stop ()
{
  if (impl_->frames_per_second_ > 0)
  {
    impl_->time_trigger_.stop ();
    impl_->running_ = false;
  }
}

///////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCDGrabberBase::isRunning () const
{
  return (impl_->running_);
}

///////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::PCDGrabberBase::getName () const
{
  return ("PCDGrabber");
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCDGrabberBase::rewind ()
{
  impl_->pcd_iterator_ = impl_->pcd_files_.begin ();
}

///////////////////////////////////////////////////////////////////////////////////////////
float
pcl::PCDGrabberBase::getFramesPerSecond () const
{
  return (impl_->frames_per_second_);
}

///////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCDGrabberBase::isRepeatOn () const
{
  return (impl_->repeat_);
}

<|endoftext|>


<commit_before>#pragma once
#include <string>
#include <vector>

namespace ipmi
{
namespace fru
{
using FruAreaData = std::vector<uint8_t>;
using Section = std::string;
using Value = std::string;
using Property = std::string;
using PropertyMap = std::map<Property, Value>;
using FruInventoryData = std::map<Section, PropertyMap>;

/**
 * @brief Builds Fru area data from inventory data
 *
 * @param[in] invData FRU properties values read from inventory
 *
 * @return FruAreaData FRU area data as per IPMI specification
 */
FruAreaData buildFruAreaData(const FruInventoryData& inventory);

} //fru
} //ipmi

<commit_msg>add missing header: map<commit_after>#pragma once

#include <map>
#include <string>
#include <vector>

namespace ipmi
{
namespace fru
{
using FruAreaData = std::vector<uint8_t>;
using Section = std::string;
using Value = std::string;
using Property = std::string;
using PropertyMap = std::map<Property, Value>;
using FruInventoryData = std::map<Section, PropertyMap>;

/**
 * @brief Builds Fru area data from inventory data
 *
 * @param[in] invData FRU properties values read from inventory
 *
 * @return FruAreaData FRU area data as per IPMI specification
 */
FruAreaData buildFruAreaData(const FruInventoryData& inventory);

} //fru
} //ipmi

<|endoftext|>


<commit_before>#pragma once

#include <utki/config.hpp>
#include <utki/debug.hpp>
#include <utki/spin_lock.hpp>

#include "../../src/opros/waitable.hpp"

#include <list>
#include <functional>

namespace helpers{

/**
 * @brief Message queue.
 * Message queue is used for communication of separate threads by
 * means of sending messages to each other. Thus, when one thread sends a message to another one,
 * it asks that another thread to execute some code portion - handler code of the message.
 * NOTE: queue implements waitable interface which means that it can be used in conjunction
 * with opros::WaitSet. But, note, that the implementation of the waitable is that it
 * shall only be used to wait for READ. If you are trying to wait for WRITE the behavior will be
 * undefined.
 */
class queue : public opros::waitable{
public:
	typedef std::function<void()> T_Message;

private:
	utki::spin_lock mut;

	std::list<T_Message> messages;

#if M_OS == M_OS_WINDOWS
	//use Event to implement waitable on Windows
	HANDLE eventForwaitable;
#elif M_OS == M_OS_MACOSX
	//use pipe to implement waitable in *nix systems
	int pipeEnds[2];
#elif M_OS == M_OS_LINUX
	//use eventfd()
	int eventFD;
#else
#	error "Unsupported OS"
#endif

	//forbid copying
	queue(const queue&);
	queue& operator=(const queue&);

public:
	/**
	 * @brief Constructor, creates empty message queue.
	 */
	queue();

	/**
	 * @brief Destructor.
	 * When called, it also destroys all messages on the queue.
	 */
	~queue()noexcept;

	/**
	 * @brief Pushes a new message to the queue.
	 * @param msg - the message to push into the queue.
	 */
	void pushMessage(T_Message&& msg)noexcept;

	/**
	 * @brief Get message from queue, does not block if no messages queued.
	 * This method gets a message from message queue. If there are no messages on the queue
	 * it will return invalid auto pointer.
	 * @return auto-pointer to Message instance.
	 * @return invalid auto-pointer if there are no messages in the queue.
	 */
	T_Message peekMsg();

#if M_OS == M_OS_WINDOWS
protected:
	HANDLE getHandle()override;

	std::uint32_t flagsMask;//flags to wait for

	void setWaitingEvents(std::uint32_t flagsToWaitFor)override;

	//returns true if signaled
	bool checkSignaled()override;

#elif M_OS == M_OS_LINUX
public:
	int getHandle()override;

#elif M_OS == M_OS_MACOSX
public:
	int getHandle()override;

#else
#	error "Unsupported OS"
#endif
};

}//~namespace
<commit_msg>msvs build fix<commit_after>#pragma once

#include <utki/config.hpp>
#include <utki/debug.hpp>
#include <utki/spin_lock.hpp>

#include "../../src/opros/waitable.hpp"

#include <list>
#include <functional>

namespace helpers{

/**
 * @brief Message queue.
 * Message queue is used for communication of separate threads by
 * means of sending messages to each other. Thus, when one thread sends a message to another one,
 * it asks that another thread to execute some code portion - handler code of the message.
 * NOTE: queue implements waitable interface which means that it can be used in conjunction
 * with opros::WaitSet. But, note, that the implementation of the waitable is that it
 * shall only be used to wait for READ. If you are trying to wait for WRITE the behavior will be
 * undefined.
 */
class queue : public opros::waitable{
public:
	typedef std::function<void()> T_Message;

private:
	utki::spin_lock mut;

	std::list<T_Message> messages;

#if M_OS == M_OS_WINDOWS
	//use Event to implement waitable on Windows
	HANDLE eventForWaitable;
#elif M_OS == M_OS_MACOSX
	//use pipe to implement waitable in *nix systems
	int pipeEnds[2];
#elif M_OS == M_OS_LINUX
	//use eventfd()
	int eventFD;
#else
#	error "Unsupported OS"
#endif

	//forbid copying
	queue(const queue&);
	queue& operator=(const queue&);

public:
	/**
	 * @brief Constructor, creates empty message queue.
	 */
	queue();

	/**
	 * @brief Destructor.
	 * When called, it also destroys all messages on the queue.
	 */
	~queue()noexcept;

	/**
	 * @brief Pushes a new message to the queue.
	 * @param msg - the message to push into the queue.
	 */
	void pushMessage(T_Message&& msg)noexcept;

	/**
	 * @brief Get message from queue, does not block if no messages queued.
	 * This method gets a message from message queue. If there are no messages on the queue
	 * it will return invalid auto pointer.
	 * @return auto-pointer to Message instance.
	 * @return invalid auto-pointer if there are no messages in the queue.
	 */
	T_Message peekMsg();

#if M_OS == M_OS_WINDOWS
protected:
	HANDLE getHandle()override;

	std::uint32_t flagsMask;//flags to wait for

	void setWaitingEvents(std::uint32_t flagsToWaitFor)override;

	//returns true if signaled
	bool checkSignaled()override;

#elif M_OS == M_OS_LINUX
public:
	int getHandle()override;

#elif M_OS == M_OS_MACOSX
public:
	int getHandle()override;

#else
#	error "Unsupported OS"
#endif
};

}//~namespace
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "aerial_autonomy/log/log.h"
#include "aerial_autonomy/tests/test_utils.h"

#include <boost/filesystem.hpp>

class LogTest : public testing::Test {
public:
  LogTest() : test_path_("/tmp/log_test") {
    std::remove(test_path_.c_str());
    config_.set_directory(test_path_);
    config_.set_write_duration(500);
    for (int i = 0; i < 4; i++) {
      DataStreamConfig *ds = config_.add_data_stream_configs();
      ds->set_stream_id(std::string("stream") + std::to_string(i));
      ds->set_delimiter(",");
      ds->set_log_rate(50);
    }
  }

  template <typename T>
  void writeToStream(std::vector<std::vector<T>> log, std::string stream_id,
                     int log_duration) {
    for (auto line : log) {
      Log::instance()[stream_id] << DataStream::startl;
      for (auto i : line) {
        Log::instance()[stream_id] << i;
      }
      Log::instance()[stream_id] << DataStream::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(log_duration));
    }
  }

protected:
  LogConfig config_;
  std::string test_path_;
};

TEST_F(LogTest, Constructor) { ASSERT_NO_THROW(Log::instance()); }

TEST_F(LogTest, OneInstance) { ASSERT_EQ(&Log::instance(), &Log::instance()); }

TEST_F(LogTest, Configure) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  ASSERT_TRUE(boost::filesystem::exists(Log::instance().directory()));
}

TEST_F(LogTest, ConfigureBadPath) {
  config_.set_directory("/");
  ASSERT_THROW(Log::instance().configure(config_), std::runtime_error);
}

TEST_F(LogTest, ConfigureStreamNotUnique) {
  DataStreamConfig *ds = config_.add_data_stream_configs();
  ds->set_stream_id("stream0");
  ASSERT_THROW(Log::instance().configure(config_), std::runtime_error);
}

TEST_F(LogTest, IndexOperator) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  ASSERT_FALSE(Log::instance()["bad_name"].configuration().log_data());

  DataStream &ds0 = Log::instance()["stream0"];
  ASSERT_EQ(ds0.configuration().stream_id(), std::string("stream0"));
  DataStream &ds1 = Log::instance()["stream1"];
  ASSERT_EQ(ds1.configuration().stream_id(), std::string("stream1"));
}

TEST_F(LogTest, AddDataStream) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  DataStreamConfig ds_config;

  ds_config.set_stream_id("new_stream");
  Log::instance().addDataStream(ds_config);

  DataStream &ds0 = Log::instance()[ds_config.stream_id()];
  ASSERT_EQ(ds0.configuration().stream_id(), ds_config.stream_id());
}

TEST_F(LogTest, Write) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  std::vector<std::vector<double>> data0 = {
      {8.8, -2.2, 3.5}, {5.6, -90.1, 4}, {3, 4, 5}};
  std::vector<std::vector<double>> data1 = {
      {6.8, -2.5, -1.5}, {5.2, -9.1, 4.1}, {3, 4.8, -5}};

  writeToStream(data0, "stream0", 30);
  writeToStream(data1, "stream1", 30);

  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      data0, Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      data1, Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
}

TEST_F(LogTest, WriteSlowRate) {
  config_.set_write_duration(1000);
  ASSERT_NO_THROW(Log::instance().configure(config_));
  std::vector<std::vector<double>> data0 = {
      {8.8, -2.2, 3.5}, {5.6, -90.1, 4}, {3, 4, 5}};
  std::vector<std::vector<double>> data1 = {
      {6.8, -2.5, -1.5}, {5.2, -9.1, 4.1}, {3, 4.8, -5}};

  writeToStream(data0, "stream0", 30);
  writeToStream(data1, "stream1", 30);

  // Check for no write
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      std::vector<std::vector<double>>(), Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      std::vector<std::vector<double>>(), Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
  // Wait for write
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      data0, Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      data1, Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Fix slow write log test by using a different directory name<commit_after>#include <gtest/gtest.h>

#include "aerial_autonomy/log/log.h"
#include "aerial_autonomy/tests/test_utils.h"

#include <boost/filesystem.hpp>

class LogTest : public testing::Test {
public:
  LogTest() : test_path_("/tmp/log_test") {
    std::remove(test_path_.c_str());
    config_.set_directory(test_path_);
    config_.set_write_duration(500);
    for (int i = 0; i < 4; i++) {
      DataStreamConfig *ds = config_.add_data_stream_configs();
      ds->set_stream_id(std::string("stream") + std::to_string(i));
      ds->set_delimiter(",");
      ds->set_log_rate(50);
    }
  }

  template <typename T>
  void writeToStream(std::vector<std::vector<T>> log, std::string stream_id,
                     int log_duration) {
    for (auto line : log) {
      Log::instance()[stream_id] << DataStream::startl;
      for (auto i : line) {
        Log::instance()[stream_id] << i;
      }
      Log::instance()[stream_id] << DataStream::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(log_duration));
    }
  }

protected:
  LogConfig config_;
  std::string test_path_;
};

TEST_F(LogTest, Constructor) { ASSERT_NO_THROW(Log::instance()); }

TEST_F(LogTest, OneInstance) { ASSERT_EQ(&Log::instance(), &Log::instance()); }

TEST_F(LogTest, Configure) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  ASSERT_TRUE(boost::filesystem::exists(Log::instance().directory()));
}

TEST_F(LogTest, ConfigureBadPath) {
  config_.set_directory("/");
  ASSERT_THROW(Log::instance().configure(config_), std::runtime_error);
}

TEST_F(LogTest, ConfigureStreamNotUnique) {
  DataStreamConfig *ds = config_.add_data_stream_configs();
  ds->set_stream_id("stream0");
  ASSERT_THROW(Log::instance().configure(config_), std::runtime_error);
}

TEST_F(LogTest, IndexOperator) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  ASSERT_FALSE(Log::instance()["bad_name"].configuration().log_data());

  DataStream &ds0 = Log::instance()["stream0"];
  ASSERT_EQ(ds0.configuration().stream_id(), std::string("stream0"));
  DataStream &ds1 = Log::instance()["stream1"];
  ASSERT_EQ(ds1.configuration().stream_id(), std::string("stream1"));
}

TEST_F(LogTest, AddDataStream) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  DataStreamConfig ds_config;

  ds_config.set_stream_id("new_stream");
  Log::instance().addDataStream(ds_config);

  DataStream &ds0 = Log::instance()[ds_config.stream_id()];
  ASSERT_EQ(ds0.configuration().stream_id(), ds_config.stream_id());
}

TEST_F(LogTest, Write) {
  ASSERT_NO_THROW(Log::instance().configure(config_));
  std::vector<std::vector<double>> data0 = {
      {8.8, -2.2, 3.5}, {5.6, -90.1, 4}, {3, 4, 5}};
  std::vector<std::vector<double>> data1 = {
      {6.8, -2.5, -1.5}, {5.2, -9.1, 4.1}, {3, 4.8, -5}};

  writeToStream(data0, "stream0", 30);
  writeToStream(data1, "stream1", 30);

  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      data0, Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      data1, Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
}

TEST_F(LogTest, WriteSlowRate) {
  config_.set_write_duration(1000);
  config_.set_directory(test_path_ + "slow");
  ASSERT_NO_THROW(Log::instance().configure(config_));
  std::vector<std::vector<double>> data0 = {
      {8.8, -2.2, 3.5}, {5.6, -90.1, 4}, {3, 4, 5}};
  std::vector<std::vector<double>> data1 = {
      {6.8, -2.5, -1.5}, {5.2, -9.1, 4.1}, {3, 4.8, -5}};

  writeToStream(data0, "stream0", 30);
  writeToStream(data1, "stream1", 30);

  // Check for no write
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      std::vector<std::vector<double>>(), Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      std::vector<std::vector<double>>(), Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
  // Wait for write
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  test_utils::verifyFileData(
      data0, Log::instance()["stream0"].path(),
      Log::instance()["stream0"].configuration().delimiter());
  test_utils::verifyFileData(
      data1, Log::instance()["stream1"].path(),
      Log::instance()["stream1"].configuration().delimiter());
}

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


<commit_before>#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_communication.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/replicated_mesh.h>
#include <libmesh/dyna_io.h>
#include <libmesh/exodusII_io.h>
#include <libmesh/dof_map.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

Number x_plus_y (const Point& p,
                 const Parameters&,
                 const std::string&,
                 const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);

  return x + y;
}

class MeshInputTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( MeshInputTest );

#if LIBMESH_DIM > 1
#ifdef LIBMESH_HAVE_EXODUS_API
  CPPUNIT_TEST( testExodusCopyElementSolution );
#ifndef LIBMESH_USE_COMPLEX_NUMBERS
  // Eventually this will support complex numbers.
  CPPUNIT_TEST( testExodusWriteElementDataFromDiscontinuousNodalData );
#endif
#endif
  CPPUNIT_TEST( testDynaReadMesh );

  CPPUNIT_TEST( testMeshMoveConstructor );
#endif // LIBMESH_DIM > 1

  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

#ifdef LIBMESH_HAVE_EXODUS_API
  void testExodusCopyElementSolution ()
  {
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("e", CONSTANT, MONOMIAL);

      MeshTools::Generation::build_square (mesh,
                                           3, 3,
                                           0., 1., 0., 1.);

      es.init();
      sys.project_solution(x_plus_y, nullptr, es.parameters);

      ExodusII_IO exii(mesh);

      // Don't try to write element data as nodal data
      std::set<std::string> sys_list;
      exii.write_equation_systems("mesh_with_soln.e", es, &sys_list);

      // Just write it as element data
      exii.write_element_data(es);
    }

    // copy_elemental_solution currently requires ReplicatedMesh
    {
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("teste", CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("mesh_with_soln.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      // Read the solution e into variable teste.
      //
      // With complex numbers, we'll only bother reading the real
      // part.
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
      exii.copy_elemental_solution(sys, "teste", "r_e");
#else
      exii.copy_elemental_solution(sys, "teste", "e");
#endif

      // Exodus only handles double precision
      Real exotol = std::max(TOLERANCE*TOLERANCE, Real(1e-12));

      for (Real x = Real(1.L/6.L); x < 1; x += Real(1.L/3.L))
        for (Real y = Real(1.L/6.L); y < 1; y += Real(1.L/3.L))
          {
            Point p(x,y);
            LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(0,p)),
                                    libmesh_real(x+y),
                                    exotol);
          }
    }
  }

#ifndef LIBMESH_USE_COMPLEX_NUMBERS
  void testExodusWriteElementDataFromDiscontinuousNodalData()
  {
    // first scope: write file
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System & sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("u", FIRST, L2_LAGRANGE);

      MeshTools::Generation::build_cube
        (mesh, 2, 2, 2, 0., 1., 0., 1., 0., 1., HEX8);

      es.init();

      // Set solution u^e_i = i, for the ith vertex of a given element e.
      const DofMap & dof_map = sys.get_dof_map();
      std::vector<dof_id_type> dof_indices;
      for (const auto & elem : mesh.element_ptr_range())
        {
          dof_map.dof_indices(elem, dof_indices, /*var_id=*/0);
          for (unsigned int i=0; i<dof_indices.size(); ++i)
            sys.solution->set(dof_indices[i], i);
        }
      sys.solution->close();

      // Now write to file.
      ExodusII_IO exii(mesh);

      // Don't try to write element data as averaged nodal data.
      std::set<std::string> sys_list;
      exii.write_equation_systems("elemental_from_nodal.e", es, &sys_list);

      // Write one elemental data field per vertex value.
      sys_list = {"SimpleSystem"};

      exii.write_element_data_from_discontinuous_nodal_data
        (es, &sys_list, /*var_suffix=*/"_elem_corner_");
    } // end first scope

    // second scope: read values back in, verify they are correct.
    {
      std::vector<std::string> file_var_names =
        {"u_elem_corner_0",
         "u_elem_corner_1",
         "u_elem_corner_2",
         "u_elem_corner_3"};
      std::vector<Real> expected_values = {0., 1., 2., 3.};

      // copy_elemental_solution currently requires ReplicatedMesh
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System & sys = es.add_system<System> ("SimpleSystem");
      for (auto i : index_range(file_var_names))
        sys.add_variable(file_var_names[i], CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("elemental_from_nodal.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      for (auto i : index_range(file_var_names))
        exii.copy_elemental_solution
          (sys, sys.variable_name(i), file_var_names[i]);

      // Check that the values we read back in are as expected.
      for (const auto & elem : mesh.active_element_ptr_range())
        for (auto i : index_range(file_var_names))
          {
            Real read_val = sys.point_value(i, elem->centroid());
            LIBMESH_ASSERT_FP_EQUAL
              (read_val, expected_values[i], TOLERANCE*TOLERANCE);
          }
    } // end second scope
  } // end testExodusWriteElementDataFromDiscontinuousNodalData

#endif // !LIBMESH_USE_COMPLEX_NUMBERS
#endif // LIBMESH_HAVE_EXODUS_API

  void testDynaReadMesh ()
  {
    Mesh mesh(*TestCommWorld);

    DynaIO dyna(mesh);
    if (mesh.processor_id() == 0)
      dyna.read("1_quad.dyn");
    MeshCommunication().broadcast (mesh);

    mesh.prepare_for_use();

    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), 1u);
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(), 9u);

    CPPUNIT_ASSERT_EQUAL(mesh.default_mapping_type(),
                         RATIONAL_BERNSTEIN_MAP);

    unsigned char weight_index = mesh.default_mapping_data();

    if (mesh.query_elem_ptr(0))
      {
        const Elem & elem = mesh.elem_ref(0);

        CPPUNIT_ASSERT_EQUAL(elem.type(), QUAD9);
        for (unsigned int n=0; n != 9; ++n)
          CPPUNIT_ASSERT_EQUAL
            (elem.node_ref(n).get_extra_datum<Real>(weight_index),
             Real(0.75));

        CPPUNIT_ASSERT_EQUAL(elem.point(0)(0), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(0)(1), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(1)(0), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(1)(1), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(2)(0), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(2)(1), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(3)(0), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(3)(1), Real(1.5));
        CPPUNIT_ASSERT(elem.has_affine_map());
#if LIBMESH_DIM > 2
        for (unsigned int v=0; v != 4; ++v)
          CPPUNIT_ASSERT_EQUAL(elem.point(v)(2), Real(0));
#endif
      }
  }

  void testMeshMoveConstructor ()
  {
    Mesh mesh(*TestCommWorld);
    MeshTools::Generation::build_square (mesh,
                                         3, 3,
                                         0., 1., 0., 1.);

    // Construct mesh2, stealing the resources of the original.
    Mesh mesh2(std::move(mesh));

    // Make sure mesh2 now has the 9 elements.
    CPPUNIT_ASSERT_EQUAL(mesh2.n_elem(),
                         static_cast<dof_id_type>(9));

    // Verify that the moved-from mesh's Partitioner and BoundaryInfo
    // objects were successfully stolen.  Note: moved-from unique_ptrs
    // are guaranteed to compare equal to nullptr, see e.g. Section
    // 20.8.1/4 of the standard.
    // https://stackoverflow.com/questions/24061767/is-unique-ptr-guaranteed-to-store-nullptr-after-move
    CPPUNIT_ASSERT(!mesh.partitioner());
    CPPUNIT_ASSERT(!mesh.boundary_info);
  }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshInputTest );
<commit_msg>Fix CPPUNIT_ASSERT for 64-bit dof_id_type<commit_after>#include <libmesh/equation_systems.h>
#include <libmesh/mesh.h>
#include <libmesh/mesh_communication.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/replicated_mesh.h>
#include <libmesh/dyna_io.h>
#include <libmesh/exodusII_io.h>
#include <libmesh/dof_map.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

Number x_plus_y (const Point& p,
                 const Parameters&,
                 const std::string&,
                 const std::string&)
{
  const Real & x = p(0);
  const Real & y = p(1);

  return x + y;
}

class MeshInputTest : public CppUnit::TestCase {
public:
  CPPUNIT_TEST_SUITE( MeshInputTest );

#if LIBMESH_DIM > 1
#ifdef LIBMESH_HAVE_EXODUS_API
  CPPUNIT_TEST( testExodusCopyElementSolution );
#ifndef LIBMESH_USE_COMPLEX_NUMBERS
  // Eventually this will support complex numbers.
  CPPUNIT_TEST( testExodusWriteElementDataFromDiscontinuousNodalData );
#endif
#endif
  CPPUNIT_TEST( testDynaReadMesh );

  CPPUNIT_TEST( testMeshMoveConstructor );
#endif // LIBMESH_DIM > 1

  CPPUNIT_TEST_SUITE_END();

private:

public:
  void setUp()
  {}

  void tearDown()
  {}

#ifdef LIBMESH_HAVE_EXODUS_API
  void testExodusCopyElementSolution ()
  {
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("e", CONSTANT, MONOMIAL);

      MeshTools::Generation::build_square (mesh,
                                           3, 3,
                                           0., 1., 0., 1.);

      es.init();
      sys.project_solution(x_plus_y, nullptr, es.parameters);

      ExodusII_IO exii(mesh);

      // Don't try to write element data as nodal data
      std::set<std::string> sys_list;
      exii.write_equation_systems("mesh_with_soln.e", es, &sys_list);

      // Just write it as element data
      exii.write_element_data(es);
    }

    // copy_elemental_solution currently requires ReplicatedMesh
    {
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System &sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("teste", CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("mesh_with_soln.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      // Read the solution e into variable teste.
      //
      // With complex numbers, we'll only bother reading the real
      // part.
#ifdef LIBMESH_USE_COMPLEX_NUMBERS
      exii.copy_elemental_solution(sys, "teste", "r_e");
#else
      exii.copy_elemental_solution(sys, "teste", "e");
#endif

      // Exodus only handles double precision
      Real exotol = std::max(TOLERANCE*TOLERANCE, Real(1e-12));

      for (Real x = Real(1.L/6.L); x < 1; x += Real(1.L/3.L))
        for (Real y = Real(1.L/6.L); y < 1; y += Real(1.L/3.L))
          {
            Point p(x,y);
            LIBMESH_ASSERT_FP_EQUAL(libmesh_real(sys.point_value(0,p)),
                                    libmesh_real(x+y),
                                    exotol);
          }
    }
  }

#ifndef LIBMESH_USE_COMPLEX_NUMBERS
  void testExodusWriteElementDataFromDiscontinuousNodalData()
  {
    // first scope: write file
    {
      Mesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System & sys = es.add_system<System> ("SimpleSystem");
      sys.add_variable("u", FIRST, L2_LAGRANGE);

      MeshTools::Generation::build_cube
        (mesh, 2, 2, 2, 0., 1., 0., 1., 0., 1., HEX8);

      es.init();

      // Set solution u^e_i = i, for the ith vertex of a given element e.
      const DofMap & dof_map = sys.get_dof_map();
      std::vector<dof_id_type> dof_indices;
      for (const auto & elem : mesh.element_ptr_range())
        {
          dof_map.dof_indices(elem, dof_indices, /*var_id=*/0);
          for (unsigned int i=0; i<dof_indices.size(); ++i)
            sys.solution->set(dof_indices[i], i);
        }
      sys.solution->close();

      // Now write to file.
      ExodusII_IO exii(mesh);

      // Don't try to write element data as averaged nodal data.
      std::set<std::string> sys_list;
      exii.write_equation_systems("elemental_from_nodal.e", es, &sys_list);

      // Write one elemental data field per vertex value.
      sys_list = {"SimpleSystem"};

      exii.write_element_data_from_discontinuous_nodal_data
        (es, &sys_list, /*var_suffix=*/"_elem_corner_");
    } // end first scope

    // second scope: read values back in, verify they are correct.
    {
      std::vector<std::string> file_var_names =
        {"u_elem_corner_0",
         "u_elem_corner_1",
         "u_elem_corner_2",
         "u_elem_corner_3"};
      std::vector<Real> expected_values = {0., 1., 2., 3.};

      // copy_elemental_solution currently requires ReplicatedMesh
      ReplicatedMesh mesh(*TestCommWorld);

      EquationSystems es(mesh);
      System & sys = es.add_system<System> ("SimpleSystem");
      for (auto i : index_range(file_var_names))
        sys.add_variable(file_var_names[i], CONSTANT, MONOMIAL);

      ExodusII_IO exii(mesh);

      if (mesh.processor_id() == 0)
        exii.read("elemental_from_nodal.e");
      MeshCommunication().broadcast(mesh);
      mesh.prepare_for_use();

      es.init();

      for (auto i : index_range(file_var_names))
        exii.copy_elemental_solution
          (sys, sys.variable_name(i), file_var_names[i]);

      // Check that the values we read back in are as expected.
      for (const auto & elem : mesh.active_element_ptr_range())
        for (auto i : index_range(file_var_names))
          {
            Real read_val = sys.point_value(i, elem->centroid());
            LIBMESH_ASSERT_FP_EQUAL
              (read_val, expected_values[i], TOLERANCE*TOLERANCE);
          }
    } // end second scope
  } // end testExodusWriteElementDataFromDiscontinuousNodalData

#endif // !LIBMESH_USE_COMPLEX_NUMBERS
#endif // LIBMESH_HAVE_EXODUS_API

  void testDynaReadMesh ()
  {
    Mesh mesh(*TestCommWorld);

    DynaIO dyna(mesh);
    if (mesh.processor_id() == 0)
      dyna.read("1_quad.dyn");
    MeshCommunication().broadcast (mesh);

    mesh.prepare_for_use();

    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), dof_id_type(1));
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(), dof_id_type(9));

    CPPUNIT_ASSERT_EQUAL(mesh.default_mapping_type(),
                         RATIONAL_BERNSTEIN_MAP);

    unsigned char weight_index = mesh.default_mapping_data();

    if (mesh.query_elem_ptr(0))
      {
        const Elem & elem = mesh.elem_ref(0);

        CPPUNIT_ASSERT_EQUAL(elem.type(), QUAD9);
        for (unsigned int n=0; n != 9; ++n)
          CPPUNIT_ASSERT_EQUAL
            (elem.node_ref(n).get_extra_datum<Real>(weight_index),
             Real(0.75));

        CPPUNIT_ASSERT_EQUAL(elem.point(0)(0), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(0)(1), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(1)(0), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(1)(1), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(2)(0), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(2)(1), Real(1.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(3)(0), Real(0.5));
        CPPUNIT_ASSERT_EQUAL(elem.point(3)(1), Real(1.5));
        CPPUNIT_ASSERT(elem.has_affine_map());
#if LIBMESH_DIM > 2
        for (unsigned int v=0; v != 4; ++v)
          CPPUNIT_ASSERT_EQUAL(elem.point(v)(2), Real(0));
#endif
      }
  }

  void testMeshMoveConstructor ()
  {
    Mesh mesh(*TestCommWorld);
    MeshTools::Generation::build_square (mesh,
                                         3, 3,
                                         0., 1., 0., 1.);

    // Construct mesh2, stealing the resources of the original.
    Mesh mesh2(std::move(mesh));

    // Make sure mesh2 now has the 9 elements.
    CPPUNIT_ASSERT_EQUAL(mesh2.n_elem(),
                         static_cast<dof_id_type>(9));

    // Verify that the moved-from mesh's Partitioner and BoundaryInfo
    // objects were successfully stolen.  Note: moved-from unique_ptrs
    // are guaranteed to compare equal to nullptr, see e.g. Section
    // 20.8.1/4 of the standard.
    // https://stackoverflow.com/questions/24061767/is-unique-ptr-guaranteed-to-store-nullptr-after-move
    CPPUNIT_ASSERT(!mesh.partitioner());
    CPPUNIT_ASSERT(!mesh.boundary_info);
  }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshInputTest );
<|endoftext|>


<commit_before>#include <boost/any.hpp>

#include "./../../Common/functor_info.hpp"

namespace utils { namespace verbose_output {
    /// @brief interface for rules tracking variable state changes
    class rule
        :    public utils::functor_info<bool(boost::any const&)>
    {
    public:
        virtual ~rule(){}

        /// @brief tests if current state changing should be logged
        ///        into the output stream
        virtual result_type operator()(args<0>::type) = 0;
    };
}}
<commit_msg>rule.hpp: added protection from multiple translating during compilation + not an abstract class<commit_after>#ifndef INC_RULE_HPP_
#define INC_RULE_HPP_

#include <boost/any.hpp>

#include "./../../Common/functor_info.hpp"

namespace utils { namespace verbose_output {
    /// @brief interface for rules tracking variable state changes
    class rule
        :    public utils::functor_info<bool(boost::any const&)>
    {
    public:
        rule(){}
        virtual ~rule(){}

        /// @brief tests if current state changing should be logged
        ///        into the output stream
        virtual result_type operator()(args<0>::type);
    };
}}

#endif
<|endoftext|>