<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef CIRCULAR_BUFFER_HH_
#define CIRCULAR_BUFFER_HH_

#include "transfer.hh"
#include "bitops.hh"
#include <memory>
#include <algorithm>

namespace seastar {

/// A growable double-ended queue container that can be efficiently
/// extended (and shrunk) from both ends. Implementation is a single
/// storage vector.
///
/// Similar to libstdc++'s std::deque, except that it uses a single
/// level store, and so is more efficient for simple stored items.
/// Similar to boost::circular_buffer_space_optimized, except it uses
/// uninitialized storage for unoccupied elements (and thus move/copy
/// constructors instead of move/copy assignments, which are less
/// efficient).
///
/// The storage of the circular_buffer is expanded automatically in
/// exponential increments.
/// When adding new elements:
/// * if size + 1 > capacity: all iterators and references are
///     invalidated,
/// * otherwise only the begin() or end() iterator is invalidated:
///     * push_front() and emplace_front() will invalidate begin() and
///     * push_back() and emplace_back() will invalidate end().
/// Removing elements never invalidates any references and only
/// invalidates begin() or end() iterators:
///     * pop_front() will invalidate begin() and
///     * pop_back() will invalidate end().
/// reserve() may also invalidate all iterators and references.
template <typename T, typename Alloc = std::allocator<T>>
class circular_buffer {
    struct impl : Alloc {
        T* storage = nullptr;
        // begin, end interpreted (mod capacity)
        size_t begin = 0;
        size_t end = 0;
        size_t capacity = 0;
    };
    impl _impl;
public:
    using value_type = T;
    using size_type = size_t;
    using reference = T&;
    using pointer = T*;
    using const_reference = const T&;
    using const_pointer = const T*;
public:
    circular_buffer() = default;
    circular_buffer(circular_buffer&& X) noexcept;
    circular_buffer(const circular_buffer& X) = delete;
    ~circular_buffer();
    circular_buffer& operator=(const circular_buffer&) = delete;
    circular_buffer& operator=(circular_buffer&& b) noexcept;
    void push_front(const T& data);
    void push_front(T&& data);
    template <typename... A>
    void emplace_front(A&&... args);
    void push_back(const T& data);
    void push_back(T&& data);
    template <typename... A>
    void emplace_back(A&&... args);
    T& front();
    T& back();
    void pop_front();
    void pop_back();
    bool empty() const;
    size_t size() const;
    size_t capacity() const;
    void reserve(size_t);
    T& operator[](size_t idx);
    template <typename Func>
    void for_each(Func func);
    // access an element, may return wrong or destroyed element
    // only useful if you do not rely on data accuracy (e.g. prefetch)
    T& access_element_unsafe(size_t idx);
private:
    void expand();
    void expand(size_t);
    void maybe_expand(size_t nr = 1);
    size_t mask(size_t idx) const;

    template<typename CB, typename ValueType>
    struct cbiterator : std::iterator<std::random_access_iterator_tag, ValueType> {
        typedef std::iterator<std::random_access_iterator_tag, ValueType> super_t;

        ValueType& operator*() const { return cb->_impl.storage[cb->mask(idx)]; }
        ValueType* operator->() const { return &cb->_impl.storage[cb->mask(idx)]; }
        // prefix
        cbiterator<CB, ValueType>& operator++() {
            idx++;
            return *this;
        }
        // postfix
        cbiterator<CB, ValueType> operator++(int unused) {
            auto v = *this;
            idx++;
            return v;
        }
        // prefix
        cbiterator<CB, ValueType>& operator--() {
            idx--;
            return *this;
        }
        // postfix
        cbiterator<CB, ValueType> operator--(int unused) {
            auto v = *this;
            idx--;
            return v;
        }
        cbiterator<CB, ValueType> operator+(typename super_t::difference_type n) const {
            return cbiterator<CB, ValueType>(cb, idx + n);
        }
        cbiterator<CB, ValueType> operator-(typename super_t::difference_type n) const {
            return cbiterator<CB, ValueType>(cb, idx - n);
        }
        cbiterator<CB, ValueType>& operator+=(typename super_t::difference_type n) {
            idx += n;
            return *this;
        }
        cbiterator<CB, ValueType>& operator-=(typename super_t::difference_type n) {
            idx -= n;
            return *this;
        }
        bool operator==(const cbiterator<CB, ValueType>& rhs) const {
            return idx == rhs.idx;
        }
        bool operator!=(const cbiterator<CB, ValueType>& rhs) const {
            return idx != rhs.idx;
        }
        bool operator<(const cbiterator<CB, ValueType>& rhs) const {
            return idx < rhs.idx;
        }
        bool operator>(const cbiterator<CB, ValueType>& rhs) const {
            return idx > rhs.idx;
        }
        bool operator>=(const cbiterator<CB, ValueType>& rhs) const {
            return idx >= rhs.idx;
        }
        bool operator<=(const cbiterator<CB, ValueType>& rhs) const {
            return idx <= rhs.idx;
        }
       typename super_t::difference_type operator-(const cbiterator<CB, ValueType>& rhs) const {
            return idx - rhs.idx;
        }
    private:
        CB* cb;
        size_t idx;
        cbiterator<CB, ValueType>(CB* b, size_t i) : cb(b), idx(i) {}
        friend class circular_buffer;
    };
    friend class iterator;

public:
    typedef cbiterator<circular_buffer, T> iterator;
    typedef cbiterator<const circular_buffer, const T> const_iterator;

    iterator begin() {
        return iterator(this, _impl.begin);
    }
    const_iterator begin() const {
        return const_iterator(this, _impl.begin);
    }
    iterator end() {
        return iterator(this, _impl.end);
    }
    const_iterator end() const {
        return const_iterator(this, _impl.end);
    }
    const_iterator cbegin() const {
        return const_iterator(this, _impl.begin);
    }
    const_iterator cend() const {
        return const_iterator(this, _impl.end);
    }
    iterator erase(iterator first, iterator last);
};

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::mask(size_t idx) const {
    return idx & (_impl.capacity - 1);
}

template <typename T, typename Alloc>
inline
bool
circular_buffer<T, Alloc>::empty() const {
    return _impl.begin == _impl.end;
}

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::size() const {
    return _impl.end - _impl.begin;
}

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::capacity() const {
    return _impl.capacity;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::reserve(size_t size) {
    if (capacity() < size) {
        // Make sure that the new capacity is a power of two.
        expand(size_t(1) << log2ceil(size));
    }
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>::circular_buffer(circular_buffer&& x) noexcept
    : _impl(std::move(x._impl)) {
    x._impl = {};
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>& circular_buffer<T, Alloc>::operator=(circular_buffer&& x) noexcept {
    if (this != &x) {
        this->~circular_buffer();
        new (this) circular_buffer(std::move(x));
    }
    return *this;
}

template <typename T, typename Alloc>
template <typename Func>
inline
void
circular_buffer<T, Alloc>::for_each(Func func) {
    auto s = _impl.storage;
    auto m = _impl.capacity - 1;
    for (auto i = _impl.begin; i != _impl.end; ++i) {
        func(s[i & m]);
    }
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>::~circular_buffer() {
    for_each([this] (T& obj) {
        _impl.destroy(&obj);
    });
    _impl.deallocate(_impl.storage, _impl.capacity);
}

template <typename T, typename Alloc>
void
circular_buffer<T, Alloc>::expand() {
    expand(std::max<size_t>(_impl.capacity * 2, 1));
}

template <typename T, typename Alloc>
void
circular_buffer<T, Alloc>::expand(size_t new_cap) {
    auto new_storage = _impl.allocate(new_cap);
    auto p = new_storage;
    try {
        for_each([this, &p] (T& obj) {
            transfer_pass1(_impl, &obj, p);
            p++;
        });
    } catch (...) {
        while (p != new_storage) {
            _impl.destroy(--p);
        }
        _impl.deallocate(new_storage, new_cap);
        throw;
    }
    p = new_storage;
    for_each([this, &p] (T& obj) {
        transfer_pass2(_impl, &obj, p++);
    });
    std::swap(_impl.storage, new_storage);
    std::swap(_impl.capacity, new_cap);
    _impl.begin = 0;
    _impl.end = p - _impl.storage;
    _impl.deallocate(new_storage, new_cap);
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::maybe_expand(size_t nr) {
    if (_impl.end - _impl.begin + nr > _impl.capacity) {
        expand();
    }
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_front(const T& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, data);
    --_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_front(T&& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, std::move(data));
    --_impl.begin;
}

template <typename T, typename Alloc>
template <typename... Args>
inline
void
circular_buffer<T, Alloc>::emplace_front(Args&&... args) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, std::forward<Args>(args)...);
    --_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_back(const T& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, data);
    ++_impl.end;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_back(T&& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, std::move(data));
    ++_impl.end;
}

template <typename T, typename Alloc>
template <typename... Args>
inline
void
circular_buffer<T, Alloc>::emplace_back(Args&&... args) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, std::forward<Args>(args)...);
    ++_impl.end;
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::front() {
    return _impl.storage[mask(_impl.begin)];
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::back() {
    return _impl.storage[mask(_impl.end - 1)];
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::pop_front() {
    _impl.destroy(&front());
    ++_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::pop_back() {
    _impl.destroy(&back());
    --_impl.end;
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::operator[](size_t idx) {
    return _impl.storage[mask(_impl.begin + idx)];
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::access_element_unsafe(size_t idx) {
    return _impl.storage[mask(_impl.begin + idx)];
}

template <typename T, typename Alloc>
inline
typename circular_buffer<T, Alloc>::iterator
circular_buffer<T, Alloc>::erase(iterator first, iterator last) {
    static_assert(std::is_nothrow_move_assignable<T>::value, "erase() assumes move assignment does not throw");
    if (first == last) {
        return last;
    }
    // Move to the left or right depending on which would result in least amount of moves.
    // This also guarantees that iterators will be stable when removing from either front or back.
    if (std::distance(begin(), first) < std::distance(last, end())) {
        auto new_start = std::move_backward(begin(), first, last);
        auto i = begin();
        while (i < new_start) {
            _impl.destroy(&*i++);
        }
        _impl.begin = new_start.idx;
        return last;
    } else {
        auto new_end = std::move(last, end(), first);
        auto i = new_end;
        auto e = end();
        while (i < e) {
            _impl.destroy(&*i++);
        }
        _impl.end = new_end.idx;
        return first;
    }
}

}

#endif /* CIRCULAR_BUFFER_HH_ */
<commit_msg>Add const version of subscript operator to circular_buffer<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef CIRCULAR_BUFFER_HH_
#define CIRCULAR_BUFFER_HH_

#include "transfer.hh"
#include "bitops.hh"
#include <memory>
#include <algorithm>

namespace seastar {

/// A growable double-ended queue container that can be efficiently
/// extended (and shrunk) from both ends. Implementation is a single
/// storage vector.
///
/// Similar to libstdc++'s std::deque, except that it uses a single
/// level store, and so is more efficient for simple stored items.
/// Similar to boost::circular_buffer_space_optimized, except it uses
/// uninitialized storage for unoccupied elements (and thus move/copy
/// constructors instead of move/copy assignments, which are less
/// efficient).
///
/// The storage of the circular_buffer is expanded automatically in
/// exponential increments.
/// When adding new elements:
/// * if size + 1 > capacity: all iterators and references are
///     invalidated,
/// * otherwise only the begin() or end() iterator is invalidated:
///     * push_front() and emplace_front() will invalidate begin() and
///     * push_back() and emplace_back() will invalidate end().
/// Removing elements never invalidates any references and only
/// invalidates begin() or end() iterators:
///     * pop_front() will invalidate begin() and
///     * pop_back() will invalidate end().
/// reserve() may also invalidate all iterators and references.
template <typename T, typename Alloc = std::allocator<T>>
class circular_buffer {
    struct impl : Alloc {
        T* storage = nullptr;
        // begin, end interpreted (mod capacity)
        size_t begin = 0;
        size_t end = 0;
        size_t capacity = 0;
    };
    impl _impl;
public:
    using value_type = T;
    using size_type = size_t;
    using reference = T&;
    using pointer = T*;
    using const_reference = const T&;
    using const_pointer = const T*;
public:
    circular_buffer() = default;
    circular_buffer(circular_buffer&& X) noexcept;
    circular_buffer(const circular_buffer& X) = delete;
    ~circular_buffer();
    circular_buffer& operator=(const circular_buffer&) = delete;
    circular_buffer& operator=(circular_buffer&& b) noexcept;
    void push_front(const T& data);
    void push_front(T&& data);
    template <typename... A>
    void emplace_front(A&&... args);
    void push_back(const T& data);
    void push_back(T&& data);
    template <typename... A>
    void emplace_back(A&&... args);
    T& front();
    T& back();
    void pop_front();
    void pop_back();
    bool empty() const;
    size_t size() const;
    size_t capacity() const;
    void reserve(size_t);
    T& operator[](size_t idx);
    const T& operator[](size_t idx) const;
    template <typename Func>
    void for_each(Func func);
    // access an element, may return wrong or destroyed element
    // only useful if you do not rely on data accuracy (e.g. prefetch)
    T& access_element_unsafe(size_t idx);
private:
    void expand();
    void expand(size_t);
    void maybe_expand(size_t nr = 1);
    size_t mask(size_t idx) const;

    template<typename CB, typename ValueType>
    struct cbiterator : std::iterator<std::random_access_iterator_tag, ValueType> {
        typedef std::iterator<std::random_access_iterator_tag, ValueType> super_t;

        ValueType& operator*() const { return cb->_impl.storage[cb->mask(idx)]; }
        ValueType* operator->() const { return &cb->_impl.storage[cb->mask(idx)]; }
        // prefix
        cbiterator<CB, ValueType>& operator++() {
            idx++;
            return *this;
        }
        // postfix
        cbiterator<CB, ValueType> operator++(int unused) {
            auto v = *this;
            idx++;
            return v;
        }
        // prefix
        cbiterator<CB, ValueType>& operator--() {
            idx--;
            return *this;
        }
        // postfix
        cbiterator<CB, ValueType> operator--(int unused) {
            auto v = *this;
            idx--;
            return v;
        }
        cbiterator<CB, ValueType> operator+(typename super_t::difference_type n) const {
            return cbiterator<CB, ValueType>(cb, idx + n);
        }
        cbiterator<CB, ValueType> operator-(typename super_t::difference_type n) const {
            return cbiterator<CB, ValueType>(cb, idx - n);
        }
        cbiterator<CB, ValueType>& operator+=(typename super_t::difference_type n) {
            idx += n;
            return *this;
        }
        cbiterator<CB, ValueType>& operator-=(typename super_t::difference_type n) {
            idx -= n;
            return *this;
        }
        bool operator==(const cbiterator<CB, ValueType>& rhs) const {
            return idx == rhs.idx;
        }
        bool operator!=(const cbiterator<CB, ValueType>& rhs) const {
            return idx != rhs.idx;
        }
        bool operator<(const cbiterator<CB, ValueType>& rhs) const {
            return idx < rhs.idx;
        }
        bool operator>(const cbiterator<CB, ValueType>& rhs) const {
            return idx > rhs.idx;
        }
        bool operator>=(const cbiterator<CB, ValueType>& rhs) const {
            return idx >= rhs.idx;
        }
        bool operator<=(const cbiterator<CB, ValueType>& rhs) const {
            return idx <= rhs.idx;
        }
       typename super_t::difference_type operator-(const cbiterator<CB, ValueType>& rhs) const {
            return idx - rhs.idx;
        }
    private:
        CB* cb;
        size_t idx;
        cbiterator<CB, ValueType>(CB* b, size_t i) : cb(b), idx(i) {}
        friend class circular_buffer;
    };
    friend class iterator;

public:
    typedef cbiterator<circular_buffer, T> iterator;
    typedef cbiterator<const circular_buffer, const T> const_iterator;

    iterator begin() {
        return iterator(this, _impl.begin);
    }
    const_iterator begin() const {
        return const_iterator(this, _impl.begin);
    }
    iterator end() {
        return iterator(this, _impl.end);
    }
    const_iterator end() const {
        return const_iterator(this, _impl.end);
    }
    const_iterator cbegin() const {
        return const_iterator(this, _impl.begin);
    }
    const_iterator cend() const {
        return const_iterator(this, _impl.end);
    }
    iterator erase(iterator first, iterator last);
};

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::mask(size_t idx) const {
    return idx & (_impl.capacity - 1);
}

template <typename T, typename Alloc>
inline
bool
circular_buffer<T, Alloc>::empty() const {
    return _impl.begin == _impl.end;
}

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::size() const {
    return _impl.end - _impl.begin;
}

template <typename T, typename Alloc>
inline
size_t
circular_buffer<T, Alloc>::capacity() const {
    return _impl.capacity;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::reserve(size_t size) {
    if (capacity() < size) {
        // Make sure that the new capacity is a power of two.
        expand(size_t(1) << log2ceil(size));
    }
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>::circular_buffer(circular_buffer&& x) noexcept
    : _impl(std::move(x._impl)) {
    x._impl = {};
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>& circular_buffer<T, Alloc>::operator=(circular_buffer&& x) noexcept {
    if (this != &x) {
        this->~circular_buffer();
        new (this) circular_buffer(std::move(x));
    }
    return *this;
}

template <typename T, typename Alloc>
template <typename Func>
inline
void
circular_buffer<T, Alloc>::for_each(Func func) {
    auto s = _impl.storage;
    auto m = _impl.capacity - 1;
    for (auto i = _impl.begin; i != _impl.end; ++i) {
        func(s[i & m]);
    }
}

template <typename T, typename Alloc>
inline
circular_buffer<T, Alloc>::~circular_buffer() {
    for_each([this] (T& obj) {
        _impl.destroy(&obj);
    });
    _impl.deallocate(_impl.storage, _impl.capacity);
}

template <typename T, typename Alloc>
void
circular_buffer<T, Alloc>::expand() {
    expand(std::max<size_t>(_impl.capacity * 2, 1));
}

template <typename T, typename Alloc>
void
circular_buffer<T, Alloc>::expand(size_t new_cap) {
    auto new_storage = _impl.allocate(new_cap);
    auto p = new_storage;
    try {
        for_each([this, &p] (T& obj) {
            transfer_pass1(_impl, &obj, p);
            p++;
        });
    } catch (...) {
        while (p != new_storage) {
            _impl.destroy(--p);
        }
        _impl.deallocate(new_storage, new_cap);
        throw;
    }
    p = new_storage;
    for_each([this, &p] (T& obj) {
        transfer_pass2(_impl, &obj, p++);
    });
    std::swap(_impl.storage, new_storage);
    std::swap(_impl.capacity, new_cap);
    _impl.begin = 0;
    _impl.end = p - _impl.storage;
    _impl.deallocate(new_storage, new_cap);
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::maybe_expand(size_t nr) {
    if (_impl.end - _impl.begin + nr > _impl.capacity) {
        expand();
    }
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_front(const T& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, data);
    --_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_front(T&& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, std::move(data));
    --_impl.begin;
}

template <typename T, typename Alloc>
template <typename... Args>
inline
void
circular_buffer<T, Alloc>::emplace_front(Args&&... args) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.begin - 1)];
    _impl.construct(p, std::forward<Args>(args)...);
    --_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_back(const T& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, data);
    ++_impl.end;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::push_back(T&& data) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, std::move(data));
    ++_impl.end;
}

template <typename T, typename Alloc>
template <typename... Args>
inline
void
circular_buffer<T, Alloc>::emplace_back(Args&&... args) {
    maybe_expand();
    auto p = &_impl.storage[mask(_impl.end)];
    _impl.construct(p, std::forward<Args>(args)...);
    ++_impl.end;
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::front() {
    return _impl.storage[mask(_impl.begin)];
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::back() {
    return _impl.storage[mask(_impl.end - 1)];
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::pop_front() {
    _impl.destroy(&front());
    ++_impl.begin;
}

template <typename T, typename Alloc>
inline
void
circular_buffer<T, Alloc>::pop_back() {
    _impl.destroy(&back());
    --_impl.end;
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::operator[](size_t idx) {
    return _impl.storage[mask(_impl.begin + idx)];
}

template <typename T, typename Alloc>
inline
const T&
circular_buffer<T, Alloc>::operator[](size_t idx) const {
    return _impl.storage[mask(_impl.begin + idx)];
}

template <typename T, typename Alloc>
inline
T&
circular_buffer<T, Alloc>::access_element_unsafe(size_t idx) {
    return _impl.storage[mask(_impl.begin + idx)];
}

template <typename T, typename Alloc>
inline
typename circular_buffer<T, Alloc>::iterator
circular_buffer<T, Alloc>::erase(iterator first, iterator last) {
    static_assert(std::is_nothrow_move_assignable<T>::value, "erase() assumes move assignment does not throw");
    if (first == last) {
        return last;
    }
    // Move to the left or right depending on which would result in least amount of moves.
    // This also guarantees that iterators will be stable when removing from either front or back.
    if (std::distance(begin(), first) < std::distance(last, end())) {
        auto new_start = std::move_backward(begin(), first, last);
        auto i = begin();
        while (i < new_start) {
            _impl.destroy(&*i++);
        }
        _impl.begin = new_start.idx;
        return last;
    } else {
        auto new_end = std::move(last, end(), first);
        auto i = new_end;
        auto e = end();
        while (i < e) {
            _impl.destroy(&*i++);
        }
        _impl.end = new_end.idx;
        return first;
    }
}

}

#endif /* CIRCULAR_BUFFER_HH_ */
<|endoftext|>


<commit_before>//===- ScriptParser.cpp ---------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the base parser class for linker script and dynamic
// list.
//
//===----------------------------------------------------------------------===//

#include "ScriptParser.h"
#include "Error.h"

using namespace llvm;
using namespace lld;
using namespace lld::elf;

// Returns the line that the character S[Pos] is in.
static StringRef getLine(StringRef S, size_t Pos) {
  size_t Begin = S.rfind('\n', Pos);
  size_t End = S.find('\n', Pos);
  Begin = (Begin == StringRef::npos) ? 0 : Begin + 1;
  if (End == StringRef::npos)
    End = S.size();
  // rtrim for DOS-style newlines.
  return S.substr(Begin, End - Begin).rtrim();
}

void ScriptParserBase::printErrorPos() {
  StringRef Tok = Tokens[Pos == 0 ? 0 : Pos - 1];
  StringRef Line = getLine(Input, Tok.data() - Input.data());
  size_t Col = Tok.data() - Line.data();
  error(Line);
  error(std::string(Col, ' ') + "^");
}

// We don't want to record cascading errors. Keep only the first one.
void ScriptParserBase::setError(const Twine &Msg) {
  if (Error)
    return;
  error("line " + Twine(getPos()) + ": " + Msg);
  printErrorPos();
  Error = true;
}

// Split S into linker script tokens.
std::vector<StringRef> ScriptParserBase::tokenize(StringRef S) {
  std::vector<StringRef> Ret;
  for (;;) {
    S = skipSpace(S);
    if (S.empty())
      return Ret;

    // Quoted token
    if (S.startswith("\"")) {
      size_t E = S.find("\"", 1);
      if (E == StringRef::npos) {
        error("unclosed quote");
        return {};
      }
      Ret.push_back(S.substr(1, E - 1));
      S = S.substr(E + 1);
      continue;
    }

    // Unquoted token
    size_t Pos = S.find_first_not_of(
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        "0123456789_.$/\\~=+[]*?-:");
    // A character that cannot start a word (which is usually a
    // punctuation) forms a single character token.
    if (Pos == 0)
      Pos = 1;
    Ret.push_back(S.substr(0, Pos));
    S = S.substr(Pos);
  }
}

// Skip leading whitespace characters or /**/-style comments.
StringRef ScriptParserBase::skipSpace(StringRef S) {
  for (;;) {
    if (S.startswith("/*")) {
      size_t E = S.find("*/", 2);
      if (E == StringRef::npos) {
        error("unclosed comment in a linker script");
        return "";
      }
      S = S.substr(E + 2);
      continue;
    }
    size_t Size = S.size();
    S = S.ltrim();
    if (S.size() == Size)
      return S;
  }
}

// An erroneous token is handled as if it were the last token before EOF.
bool ScriptParserBase::atEOF() { return Error || Tokens.size() == Pos; }

StringRef ScriptParserBase::next() {
  if (Error)
    return "";
  if (atEOF()) {
    setError("unexpected EOF");
    return "";
  }
  return Tokens[Pos++];
}

StringRef ScriptParserBase::peek() {
  StringRef Tok = next();
  if (Error)
    return "";
  --Pos;
  return Tok;
}

bool ScriptParserBase::skip(StringRef Tok) {
  if (Error)
    return false;
  if (atEOF()) {
    setError("unexpected EOF");
    return false;
  }
  if (Tokens[Pos] != Tok)
    return false;
  ++Pos;
  return true;
}

void ScriptParserBase::expect(StringRef Expect) {
  if (Error)
    return;
  StringRef Tok = next();
  if (Tok != Expect)
    setError(Expect + " expected, but got " + Tok);
}

// Returns the current line number.
size_t ScriptParserBase::getPos() {
  if (Pos == 0)
    return 1;
  const char *Begin = Input.data();
  const char *Tok = Tokens[Pos - 1].data();
  return StringRef(Begin, Tok - Begin).count('\n') + 1;
}

std::vector<uint8_t> ScriptParserBase::parseHex(StringRef S) {
  std::vector<uint8_t> Hex;
  while (!S.empty()) {
    StringRef B = S.substr(0, 2);
    S = S.substr(2);
    uint8_t H;
    if (B.getAsInteger(16, H)) {
      setError("not a hexadecimal value: " + B);
      return {};
    }
    Hex.push_back(H);
  }
  return Hex;
}
<commit_msg>[ELF] Include Twine.h header to restore LLD build after r266524. NFC<commit_after>//===- ScriptParser.cpp ---------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the base parser class for linker script and dynamic
// list.
//
//===----------------------------------------------------------------------===//

#include "ScriptParser.h"
#include "Error.h"
#include "llvm/ADT/Twine.h"

using namespace llvm;
using namespace lld;
using namespace lld::elf;

// Returns the line that the character S[Pos] is in.
static StringRef getLine(StringRef S, size_t Pos) {
  size_t Begin = S.rfind('\n', Pos);
  size_t End = S.find('\n', Pos);
  Begin = (Begin == StringRef::npos) ? 0 : Begin + 1;
  if (End == StringRef::npos)
    End = S.size();
  // rtrim for DOS-style newlines.
  return S.substr(Begin, End - Begin).rtrim();
}

void ScriptParserBase::printErrorPos() {
  StringRef Tok = Tokens[Pos == 0 ? 0 : Pos - 1];
  StringRef Line = getLine(Input, Tok.data() - Input.data());
  size_t Col = Tok.data() - Line.data();
  error(Line);
  error(std::string(Col, ' ') + "^");
}

// We don't want to record cascading errors. Keep only the first one.
void ScriptParserBase::setError(const Twine &Msg) {
  if (Error)
    return;
  error("line " + Twine(getPos()) + ": " + Msg);
  printErrorPos();
  Error = true;
}

// Split S into linker script tokens.
std::vector<StringRef> ScriptParserBase::tokenize(StringRef S) {
  std::vector<StringRef> Ret;
  for (;;) {
    S = skipSpace(S);
    if (S.empty())
      return Ret;

    // Quoted token
    if (S.startswith("\"")) {
      size_t E = S.find("\"", 1);
      if (E == StringRef::npos) {
        error("unclosed quote");
        return {};
      }
      Ret.push_back(S.substr(1, E - 1));
      S = S.substr(E + 1);
      continue;
    }

    // Unquoted token
    size_t Pos = S.find_first_not_of(
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        "0123456789_.$/\\~=+[]*?-:");
    // A character that cannot start a word (which is usually a
    // punctuation) forms a single character token.
    if (Pos == 0)
      Pos = 1;
    Ret.push_back(S.substr(0, Pos));
    S = S.substr(Pos);
  }
}

// Skip leading whitespace characters or /**/-style comments.
StringRef ScriptParserBase::skipSpace(StringRef S) {
  for (;;) {
    if (S.startswith("/*")) {
      size_t E = S.find("*/", 2);
      if (E == StringRef::npos) {
        error("unclosed comment in a linker script");
        return "";
      }
      S = S.substr(E + 2);
      continue;
    }
    size_t Size = S.size();
    S = S.ltrim();
    if (S.size() == Size)
      return S;
  }
}

// An erroneous token is handled as if it were the last token before EOF.
bool ScriptParserBase::atEOF() { return Error || Tokens.size() == Pos; }

StringRef ScriptParserBase::next() {
  if (Error)
    return "";
  if (atEOF()) {
    setError("unexpected EOF");
    return "";
  }
  return Tokens[Pos++];
}

StringRef ScriptParserBase::peek() {
  StringRef Tok = next();
  if (Error)
    return "";
  --Pos;
  return Tok;
}

bool ScriptParserBase::skip(StringRef Tok) {
  if (Error)
    return false;
  if (atEOF()) {
    setError("unexpected EOF");
    return false;
  }
  if (Tokens[Pos] != Tok)
    return false;
  ++Pos;
  return true;
}

void ScriptParserBase::expect(StringRef Expect) {
  if (Error)
    return;
  StringRef Tok = next();
  if (Tok != Expect)
    setError(Expect + " expected, but got " + Tok);
}

// Returns the current line number.
size_t ScriptParserBase::getPos() {
  if (Pos == 0)
    return 1;
  const char *Begin = Input.data();
  const char *Tok = Tokens[Pos - 1].data();
  return StringRef(Begin, Tok - Begin).count('\n') + 1;
}

std::vector<uint8_t> ScriptParserBase::parseHex(StringRef S) {
  std::vector<uint8_t> Hex;
  while (!S.empty()) {
    StringRef B = S.substr(0, 2);
    S = S.substr(2);
    uint8_t H;
    if (B.getAsInteger(16, H)) {
      setError("not a hexadecimal value: " + B);
      return {};
    }
    Hex.push_back(H);
  }
  return Hex;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "file/nifti_utils.h"
#include "formats/list.h"

namespace MR
{
  namespace Formats
  {

    std::unique_ptr<ImageIO::Base> NIfTI2::read (Header& H) const
    {
      return File::NIfTI::read<2> (H);
    }

    bool NIfTI2::check (Header& H, size_t num_axes) const
    {
      const vector<std::string> suffixes { ".nii" };
      return File::NIfTI::check (H, num_axes, false, suffixes, 2, "NIfTI-2");
    }

    std::unique_ptr<ImageIO::Base> NIfTI2::create (Header& H) const
    {
      return File::NIfTI::create<2> (H);
    }

  }
}

<commit_msg>NIfTI-2: reinstate .img in list of suffixes<commit_after>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "file/nifti_utils.h"
#include "formats/list.h"

namespace MR
{
  namespace Formats
  {

    std::unique_ptr<ImageIO::Base> NIfTI2::read (Header& H) const
    {
      return File::NIfTI::read<2> (H);
    }

    bool NIfTI2::check (Header& H, size_t num_axes) const
    {
      const vector<std::string> suffixes { ".nii", ".img" };
      return File::NIfTI::check (H, num_axes, false, suffixes, 2, "NIfTI-2");
    }

    std::unique_ptr<ImageIO::Base> NIfTI2::create (Header& H) const
    {
      return File::NIfTI::create<2> (H);
    }

  }
}

<|endoftext|>


<commit_before>#include "core/hashgen_sprator.h"

#include <vector>

#include "core/image.h"
#include "core/rgb.h"
#include "core/assert.h"
#include "core/rng.h"
#include "core/numeric.h"
#include "core/image_draw.h"
#include "core/cint.h"
#include "core/table_bool.h"
#include "core/generator_cell.h"

namespace
{
    using namespace euphoria::core;

    Rgbai
    CalculateBorderColor(Rgbai base)
    {
        auto h = hsl(rgb(base));
        h.h -= Angle::FromDegrees(15);
        h.l *= 0.4;
        return {rgbi(rgb(h)), base.a};
    }

    void
    ApplySpratorAlgorithm(BoolTable* half_side, int number_of_steps)
    {
        generator::Rules rules;
        generator::AddComplexRules
        (
            &rules,
            number_of_steps,
            [](bool current, const Wallcounter& wc) -> std::optional<bool>
            {
                const auto c = wc.Count
                (
                    1,
                    false,
                    NeighborhoodAlgorithm::Plus
                );
                if(current)
                {
                    if(c == 2 || c == 3 ) { return true; }
                    else { return false; }
                }
                else
                {
                    if(c <= 1) { return true; }
                    else { return false; }
                }
            }
        );

        auto cell = generator::CellularAutomata
        (
            &rules,
            half_side,
            Fourway<OutsideRule>{OutsideRule::Empty}
        );

        while(cell.HasMoreWork()) { cell.Work(); }
    }

    BoolTable
    Mirror(const BoolTable& half_side)
    {
        const auto height = half_side.GetHeight();
        const auto half_width = half_side.GetWidth();
        const auto width = half_width * 2;

        // offset everything by 1 to get a nice border
        constexpr auto offset = 1;
        constexpr auto extra_size = 2;

        auto result_table = BoolTable::FromWidthHeight
        (
            width + extra_size,
            height + extra_size,
            false
        );

        for(int y=0; y<height; y+=1)
        for(int x=0; x<half_width; x+=1)
        {
            const auto src = half_side(x, y);
            const auto x_mirror = width - (x + 1);
            result_table(x + offset, y + offset) = src;
            result_table(x_mirror + offset, y + offset) = src;
        }

        return result_table;
    }

    int
    CalculateScale(const Image& image, const BoolTable& table)
    {
        auto calculate_scale = [](int image_scale, int table_scale) -> int
        {
            const auto image_scale_float = static_cast<float>(image_scale);
            const auto table_scale_float = static_cast<float>(table_scale);
            const auto scale_factor = image_scale_float / table_scale_float;
            return std::max(1, Floori(scale_factor));
        };

        const auto scale = std::min
        (
            calculate_scale(image.GetWidth(), table.GetWidth()),
            calculate_scale(image.GetHeight(), table.GetHeight())
        );

        return scale;
    }

    void
    DrawImageWithBorder
    (
        Image* image,
        const BoolTable& result_table,
        const Rgbai& background_color,
        const Rgbai& foreground_color,
        const Rgbai& border_color
    )
    {
        Clear(image, background_color);
        auto img = Draw
        (
            result_table,
            foreground_color,
            background_color,
            CalculateScale(*image, result_table),
            BorderSettings{border_color}
        );
        PasteImage(image, vec2i{0, 0}, img);
    }

    template
    <
        typename TGenerator
    >
    void
    RandomizeWorld(BoolTable* half_side, TGenerator* generator)
    {
        SetWhiteNoise
        (
            half_side,
            Fourway<BorderSetupRule>{BorderSetupRule::Random},
            [&]() -> bool { return generator->Next() < 0.5f; }
        );
    }

    template
    <
        typename TGenerator,
        typename I
    >
    void
    RenderSpratorImpl
    (
        Image* image,
        I code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        constexpr int half_width = 4;
        constexpr int height = 8;
        const int number_of_steps = 3;
        // todo(Gustav): figure out color (randomly?)
        const Rgbai border_color = border_color_arg.value_or
        (
            CalculateBorderColor(foreground_color)
        );

        auto half_side = BoolTable::FromWidthHeight(half_width, height);

        auto generator = TGenerator{code};

        // randomize world
        RandomizeWorld<TGenerator>(&half_side, &generator);

        // apply sprator algorithm
        ApplySpratorAlgorithm(&half_side, number_of_steps);

        // flip and copy from small table to big table
        const auto result_table = Mirror(half_side);

        // draw image with border
        DrawImageWithBorder(image, result_table, background_color, foreground_color, border_color);
    }

    template
    <
        typename TGenerator,
        typename I
    >
    void
    RenderSpratorImpl
    (
        std::vector<Image>* images,
        I code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        constexpr int half_width = 4;
        constexpr int height = 8;
        const int number_of_steps = 3;
        // todo(Gustav): figure out color (randomly?)
        const Rgbai border_color = border_color_arg.value_or
        (
            CalculateBorderColor(foreground_color)
        );

        auto half_side = BoolTable::FromWidthHeight(half_width, height);

        auto generator = TGenerator{code};

        // randomize world
        RandomizeWorld<TGenerator>(&half_side, &generator);

        // apply sprator algorithm
        ApplySpratorAlgorithm(&half_side, number_of_steps);

        bool first = true;

        auto orig_half_side = half_side;

        for(auto& image: *images)
        {
            if(first) { first = false; }
            else
            {
                half_side = orig_half_side;

                // animate...
                auto hit = BoolTable::FromWidthHeight(half_side.GetWidth(), half_side.GetHeight(), false);
                for(int i=0; i<2; i+=1)
                {
                    int x = 0;
                    int y = 0;
                    do
                    {
                        x = Floori(generator.Next() * half_side.GetWidth());
                        y = Floori(generator.Next() * half_side.GetHeight());
                    } while(hit(x, y));
                    hit(x, y) = true;
                    half_side(x, y) = !half_side(x, y);
                }
            }

            // flip and copy from small table to big table
            const auto result_table = Mirror(half_side);

            // draw image with border
            DrawImageWithBorder(&image, result_table, background_color, foreground_color, border_color);
        }
    }
}

namespace euphoria::core
{
    void
    RenderSprator
    (
        Image* image,
        int code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        RenderSpratorImpl<xorshift32>
        (
            image,
            Cbit_signed_to_unsigned(code),
            foreground_color,
            border_color_arg,
            background_color
        );
    }

    void
    RenderSprator
    (
        std::vector<Image>* images,
        int code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        RenderSpratorImpl<xorshift32>
        (
            images,
            Cbit_signed_to_unsigned(code),
            foreground_color,
            border_color_arg,
            background_color
        );
    }
}

<commit_msg>sprator step after animation<commit_after>#include "core/hashgen_sprator.h"

#include <vector>

#include "core/image.h"
#include "core/rgb.h"
#include "core/assert.h"
#include "core/rng.h"
#include "core/numeric.h"
#include "core/image_draw.h"
#include "core/cint.h"
#include "core/table_bool.h"
#include "core/generator_cell.h"

namespace
{
    using namespace euphoria::core;

    Rgbai
    CalculateBorderColor(Rgbai base)
    {
        auto h = hsl(rgb(base));
        h.h -= Angle::FromDegrees(15);
        h.l *= 0.4;
        return {rgbi(rgb(h)), base.a};
    }

    void
    ApplySpratorAlgorithm(BoolTable* half_side, int number_of_steps)
    {
        generator::Rules rules;
        generator::AddComplexRules
        (
            &rules,
            number_of_steps,
            [](bool current, const Wallcounter& wc) -> std::optional<bool>
            {
                const auto c = wc.Count
                (
                    1,
                    false,
                    NeighborhoodAlgorithm::Plus
                );
                if(current)
                {
                    if(c == 2 || c == 3 ) { return true; }
                    else { return false; }
                }
                else
                {
                    if(c <= 1) { return true; }
                    else { return false; }
                }
            }
        );

        auto cell = generator::CellularAutomata
        (
            &rules,
            half_side,
            Fourway<OutsideRule>{OutsideRule::Empty}
        );

        while(cell.HasMoreWork()) { cell.Work(); }
    }

    BoolTable
    Mirror(const BoolTable& half_side)
    {
        const auto height = half_side.GetHeight();
        const auto half_width = half_side.GetWidth();
        const auto width = half_width * 2;

        // offset everything by 1 to get a nice border
        constexpr auto offset = 1;
        constexpr auto extra_size = 2;

        auto result_table = BoolTable::FromWidthHeight
        (
            width + extra_size,
            height + extra_size,
            false
        );

        for(int y=0; y<height; y+=1)
        for(int x=0; x<half_width; x+=1)
        {
            const auto src = half_side(x, y);
            const auto x_mirror = width - (x + 1);
            result_table(x + offset, y + offset) = src;
            result_table(x_mirror + offset, y + offset) = src;
        }

        return result_table;
    }

    int
    CalculateScale(const Image& image, const BoolTable& table)
    {
        auto calculate_scale = [](int image_scale, int table_scale) -> int
        {
            const auto image_scale_float = static_cast<float>(image_scale);
            const auto table_scale_float = static_cast<float>(table_scale);
            const auto scale_factor = image_scale_float / table_scale_float;
            return std::max(1, Floori(scale_factor));
        };

        const auto scale = std::min
        (
            calculate_scale(image.GetWidth(), table.GetWidth()),
            calculate_scale(image.GetHeight(), table.GetHeight())
        );

        return scale;
    }

    void
    DrawImageWithBorder
    (
        Image* image,
        const BoolTable& result_table,
        const Rgbai& background_color,
        const Rgbai& foreground_color,
        const Rgbai& border_color
    )
    {
        Clear(image, background_color);
        auto img = Draw
        (
            result_table,
            foreground_color,
            background_color,
            CalculateScale(*image, result_table),
            BorderSettings{border_color}
        );
        PasteImage(image, vec2i{0, 0}, img);
    }

    template
    <
        typename TGenerator
    >
    void
    RandomizeWorld(BoolTable* half_side, TGenerator* generator)
    {
        SetWhiteNoise
        (
            half_side,
            Fourway<BorderSetupRule>{BorderSetupRule::Random},
            [&]() -> bool { return generator->Next() < 0.5f; }
        );
    }

    template
    <
        typename TGenerator,
        typename I
    >
    void
    RenderSpratorImpl
    (
        Image* image,
        I code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        constexpr int half_width = 4;
        constexpr int height = 8;
        const int number_of_steps = 3;
        // todo(Gustav): figure out color (randomly?)
        const Rgbai border_color = border_color_arg.value_or
        (
            CalculateBorderColor(foreground_color)
        );

        auto half_side = BoolTable::FromWidthHeight(half_width, height);

        auto generator = TGenerator{code};

        // randomize world
        RandomizeWorld<TGenerator>(&half_side, &generator);

        // apply sprator algorithm
        ApplySpratorAlgorithm(&half_side, number_of_steps);

        // flip and copy from small table to big table
        const auto result_table = Mirror(half_side);

        // draw image with border
        DrawImageWithBorder(image, result_table, background_color, foreground_color, border_color);
    }

    template
    <
        typename TGenerator,
        typename I
    >
    void
    RenderSpratorImpl
    (
        std::vector<Image>* images,
        I code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        constexpr int half_width = 4;
        constexpr int height = 8;
        const int number_of_steps = 3;
        // todo(Gustav): figure out color (randomly?)
        const Rgbai border_color = border_color_arg.value_or
        (
            CalculateBorderColor(foreground_color)
        );

        auto half_side = BoolTable::FromWidthHeight(half_width, height);

        auto generator = TGenerator{code};

        // randomize world
        RandomizeWorld<TGenerator>(&half_side, &generator);

        // apply sprator algorithm
        ApplySpratorAlgorithm(&half_side, number_of_steps - 1);

        bool first = true;

        auto orig_half_side = half_side;

        for(auto& image: *images)
        {
            if(first) { first = false; }
            else
            {
                half_side = orig_half_side;

                // animate...
                auto hit = BoolTable::FromWidthHeight(half_side.GetWidth(), half_side.GetHeight(), false);
                for(int i=0; i<2; i+=1)
                {
                    int x = 0;
                    int y = 0;
                    do
                    {
                        x = Floori(generator.Next() * half_side.GetWidth());
                        y = Floori(generator.Next() * half_side.GetHeight());
                    } while(hit(x, y));
                    hit(x, y) = true;
                    half_side(x, y) = !half_side(x, y);
                }
            }

            ApplySpratorAlgorithm(&half_side, 1);

            // flip and copy from small table to big table
            const auto result_table = Mirror(half_side);

            // draw image with border
            DrawImageWithBorder(&image, result_table, background_color, foreground_color, border_color);
        }
    }
}

namespace euphoria::core
{
    void
    RenderSprator
    (
        Image* image,
        int code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        RenderSpratorImpl<xorshift32>
        (
            image,
            Cbit_signed_to_unsigned(code),
            foreground_color,
            border_color_arg,
            background_color
        );
    }

    void
    RenderSprator
    (
        std::vector<Image>* images,
        int code,
        const Rgbai& foreground_color,
        const std::optional<Rgbai> border_color_arg,
        const Rgbai& background_color
    )
    {
        RenderSpratorImpl<xorshift32>
        (
            images,
            Cbit_signed_to_unsigned(code),
            foreground_color,
            border_color_arg,
            background_color
        );
    }
}

<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkTool.h"
#include "mitkDataTreeNodeFactory.h"
#include "mitkOrganTypeProperty.h"
#include "mitkProperties.h"
#include "mitkLevelWindowProperty.h"
#include "mitkVtkResliceInterpolationProperty.h"

#include <itkObjectFactory.h>

mitk::Tool::Tool(const char* type)
: StateMachine(type),
  // for working image
  m_IsSegmentationPredicate(NodePredicateProperty::New("segmentation", BoolProperty::New(true))),
  // for reference images
  m_PredicateImages(NodePredicateDataType::New("Image")),
  m_PredicateDim3(NodePredicateDimension::New(3, 1)),
  m_PredicateDim4(NodePredicateDimension::New(4, 1)),
  m_PredicateDimension( mitk::NodePredicateOR::New(m_PredicateDim3, m_PredicateDim4) ),
  m_PredicateImage3D( NodePredicateAND::New(m_PredicateImages, m_PredicateDimension) ),

  m_PredicateBinary(NodePredicateProperty::New("binary", BoolProperty::New(true))),
  m_PredicateNotBinary( NodePredicateNOT::New(m_PredicateBinary) ),

  m_PredicateSegmentation(NodePredicateProperty::New("segmentation", BoolProperty::New(true))),
  m_PredicateNotSegmentation( NodePredicateNOT::New(m_PredicateSegmentation) ),

  m_PredicateHelper(NodePredicateProperty::New("helper object", BoolProperty::New(true))),
  m_PredicateNotHelper( NodePredicateNOT::New(m_PredicateHelper) ),

  m_PredicateImageColorful( NodePredicateAND::New(m_PredicateNotBinary, m_PredicateNotSegmentation) ),

  m_PredicateImageColorfulNotHelper( NodePredicateAND::New(m_PredicateImageColorful, m_PredicateNotHelper) ),

  m_PredicateReference( NodePredicateAND::New(m_PredicateImage3D, m_PredicateImageColorfulNotHelper) )
{
}

mitk::Tool::~Tool()
{
}

const char* mitk::Tool::GetGroup() const
{
  return "default";
}

void mitk::Tool::SetToolManager(ToolManager* manager)
{
  m_ToolManager = manager;
}

void mitk::Tool::Activated()
{
}

void mitk::Tool::Deactivated()
{
  StateMachine::ResetStatemachineToStartState(); // forget about the past
}

itk::Object::Pointer mitk::Tool::GetGUI(const std::string& toolkitPrefix, const std::string& toolkitPostfix)
{
  itk::Object::Pointer object;

  std::string classname = this->GetNameOfClass();
  std::string guiClassname = toolkitPrefix + classname + toolkitPostfix;

  std::list<itk::LightObject::Pointer> allGUIs = itk::ObjectFactoryBase::CreateAllInstance(guiClassname.c_str());
  for( std::list<itk::LightObject::Pointer>::iterator iter = allGUIs.begin();
       iter != allGUIs.end();
       ++iter )
  {
    if (object.IsNull())
    {
      object = dynamic_cast<itk::Object*>( iter->GetPointer() );
    }
    else
    {
      LOG_ERROR << "There is more than one GUI for " << classname << " (several factories claim ability to produce a " << guiClassname << " ) " << std::endl;
      return NULL; // people should see and fix this error
    }
  }

  return object;
}

mitk::NodePredicateBase::ConstPointer mitk::Tool::GetReferenceDataPreference() const
{
  return m_PredicateReference.GetPointer();
}

mitk::NodePredicateBase::ConstPointer mitk::Tool::GetWorkingDataPreference() const
{
  return m_IsSegmentationPredicate.GetPointer();
}

mitk::DataTreeNode::Pointer mitk::Tool::CreateEmptySegmentationNode( Image* original, const std::string& organType, const std::string& organName )
{
  // we NEED a reference image for size etc.
  if (!original) return NULL;

  // actually create a new empty segmentation
  PixelType pixelType( typeid(DefaultSegmentationDataType) );
  Image::Pointer segmentation = Image::New();
  segmentation->SetProperty( "organ type", OrganTypeProperty::New( organType ) );
  segmentation->Initialize( pixelType, original->GetDimension(), original->GetDimensions() );

  unsigned int byteSize = sizeof(DefaultSegmentationDataType);
  for (unsigned int dim = 0; dim < segmentation->GetDimension(); ++dim)
  {
    byteSize *= segmentation->GetDimension(dim);
  }
  memset( segmentation->GetData(), 0, byteSize );

  if (original->GetTimeSlicedGeometry() )
  {
    AffineGeometryFrame3D::Pointer originalGeometryAGF = original->GetTimeSlicedGeometry()->Clone();
    TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() );
    segmentation->SetGeometry( originalGeometry );
  }
  else
  {
    Tool::ErrorMessage("Original image does not have a 'Time sliced geometry'! Cannot create a segmentation.");
    return NULL;
  }

  return CreateSegmentationNode( segmentation, organType, organName );
}

mitk::DataTreeNode::Pointer mitk::Tool::CreateSegmentationNode( Image* image, const std::string& organType, const std::string& organName )
{
  if (!image) return NULL;

  // decorate the datatreenode with some properties
  DataTreeNode::Pointer segmentationNode = DataTreeNode::New();
  segmentationNode->SetData( image );

  // name
  segmentationNode->SetProperty( "name", StringProperty::New( organName ) );

  // organ type
  OrganTypeProperty::Pointer organTypeProperty = OrganTypeProperty::New( organType );
  if ( !organTypeProperty->IsValidEnumerationValue( organType ) )
  {
    organTypeProperty->AddEnum( organType, organTypeProperty->Size() ); // add a new organ type
    organTypeProperty->SetValue( organType );
  }

  // visualization properties
  segmentationNode->SetProperty( "binary", BoolProperty::New(true) );
  segmentationNode->SetProperty( "color", DataTreeNodeFactory::DefaultColorForOrgan( organType ) );
  segmentationNode->SetProperty( "texture interpolation", BoolProperty::New(false) );
  segmentationNode->SetProperty( "layer", IntProperty::New(10) );
  segmentationNode->SetProperty( "levelwindow", LevelWindowProperty::New( LevelWindow(0.5, 1) ) );
  segmentationNode->SetProperty( "opacity", FloatProperty::New(0.3) );
  segmentationNode->SetProperty( "segmentation", BoolProperty::New(true) );
  segmentationNode->SetProperty( "reslice interpolation", VtkResliceInterpolationProperty::New() ); // otherwise -> segmentation appears in 2 slices sometimes (only visual effect, not different data)

  return segmentationNode;
}

<commit_msg>CHG (#273): Readded property "showVolume" on segmentation images to let the ImageMapper2D show the volume annotation.<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkTool.h"
#include "mitkDataTreeNodeFactory.h"
#include "mitkOrganTypeProperty.h"
#include "mitkProperties.h"
#include "mitkLevelWindowProperty.h"
#include "mitkVtkResliceInterpolationProperty.h"

#include <itkObjectFactory.h>

mitk::Tool::Tool(const char* type)
: StateMachine(type),
  // for working image
  m_IsSegmentationPredicate(NodePredicateProperty::New("segmentation", BoolProperty::New(true))),
  // for reference images
  m_PredicateImages(NodePredicateDataType::New("Image")),
  m_PredicateDim3(NodePredicateDimension::New(3, 1)),
  m_PredicateDim4(NodePredicateDimension::New(4, 1)),
  m_PredicateDimension( mitk::NodePredicateOR::New(m_PredicateDim3, m_PredicateDim4) ),
  m_PredicateImage3D( NodePredicateAND::New(m_PredicateImages, m_PredicateDimension) ),

  m_PredicateBinary(NodePredicateProperty::New("binary", BoolProperty::New(true))),
  m_PredicateNotBinary( NodePredicateNOT::New(m_PredicateBinary) ),

  m_PredicateSegmentation(NodePredicateProperty::New("segmentation", BoolProperty::New(true))),
  m_PredicateNotSegmentation( NodePredicateNOT::New(m_PredicateSegmentation) ),

  m_PredicateHelper(NodePredicateProperty::New("helper object", BoolProperty::New(true))),
  m_PredicateNotHelper( NodePredicateNOT::New(m_PredicateHelper) ),

  m_PredicateImageColorful( NodePredicateAND::New(m_PredicateNotBinary, m_PredicateNotSegmentation) ),

  m_PredicateImageColorfulNotHelper( NodePredicateAND::New(m_PredicateImageColorful, m_PredicateNotHelper) ),

  m_PredicateReference( NodePredicateAND::New(m_PredicateImage3D, m_PredicateImageColorfulNotHelper) )
{
}

mitk::Tool::~Tool()
{
}

const char* mitk::Tool::GetGroup() const
{
  return "default";
}

void mitk::Tool::SetToolManager(ToolManager* manager)
{
  m_ToolManager = manager;
}

void mitk::Tool::Activated()
{
}

void mitk::Tool::Deactivated()
{
  StateMachine::ResetStatemachineToStartState(); // forget about the past
}

itk::Object::Pointer mitk::Tool::GetGUI(const std::string& toolkitPrefix, const std::string& toolkitPostfix)
{
  itk::Object::Pointer object;

  std::string classname = this->GetNameOfClass();
  std::string guiClassname = toolkitPrefix + classname + toolkitPostfix;

  std::list<itk::LightObject::Pointer> allGUIs = itk::ObjectFactoryBase::CreateAllInstance(guiClassname.c_str());
  for( std::list<itk::LightObject::Pointer>::iterator iter = allGUIs.begin();
       iter != allGUIs.end();
       ++iter )
  {
    if (object.IsNull())
    {
      object = dynamic_cast<itk::Object*>( iter->GetPointer() );
    }
    else
    {
      LOG_ERROR << "There is more than one GUI for " << classname << " (several factories claim ability to produce a " << guiClassname << " ) " << std::endl;
      return NULL; // people should see and fix this error
    }
  }

  return object;
}

mitk::NodePredicateBase::ConstPointer mitk::Tool::GetReferenceDataPreference() const
{
  return m_PredicateReference.GetPointer();
}

mitk::NodePredicateBase::ConstPointer mitk::Tool::GetWorkingDataPreference() const
{
  return m_IsSegmentationPredicate.GetPointer();
}

mitk::DataTreeNode::Pointer mitk::Tool::CreateEmptySegmentationNode( Image* original, const std::string& organType, const std::string& organName )
{
  // we NEED a reference image for size etc.
  if (!original) return NULL;

  // actually create a new empty segmentation
  PixelType pixelType( typeid(DefaultSegmentationDataType) );
  Image::Pointer segmentation = Image::New();
  segmentation->SetProperty( "organ type", OrganTypeProperty::New( organType ) );

  segmentation->Initialize( pixelType, original->GetDimension(), original->GetDimensions() );

  unsigned int byteSize = sizeof(DefaultSegmentationDataType);
  for (unsigned int dim = 0; dim < segmentation->GetDimension(); ++dim)
  {
    byteSize *= segmentation->GetDimension(dim);
  }
  memset( segmentation->GetData(), 0, byteSize );

  if (original->GetTimeSlicedGeometry() )
  {
    AffineGeometryFrame3D::Pointer originalGeometryAGF = original->GetTimeSlicedGeometry()->Clone();
    TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() );
    segmentation->SetGeometry( originalGeometry );
  }
  else
  {
    Tool::ErrorMessage("Original image does not have a 'Time sliced geometry'! Cannot create a segmentation.");
    return NULL;
  }

  return CreateSegmentationNode( segmentation, organType, organName );
}

mitk::DataTreeNode::Pointer mitk::Tool::CreateSegmentationNode( Image* image, const std::string& organType, const std::string& organName )
{
  if (!image) return NULL;

  // decorate the datatreenode with some properties
  DataTreeNode::Pointer segmentationNode = DataTreeNode::New();
  segmentationNode->SetData( image );

  // name
  segmentationNode->SetProperty( "name", StringProperty::New( organName ) );

  // organ type
  OrganTypeProperty::Pointer organTypeProperty = OrganTypeProperty::New( organType );
  if ( !organTypeProperty->IsValidEnumerationValue( organType ) )
  {
    organTypeProperty->AddEnum( organType, organTypeProperty->Size() ); // add a new organ type
    organTypeProperty->SetValue( organType );
  }

  // visualization properties
  segmentationNode->SetProperty( "binary", BoolProperty::New(true) );
  segmentationNode->SetProperty( "color", DataTreeNodeFactory::DefaultColorForOrgan( organType ) );
  segmentationNode->SetProperty( "texture interpolation", BoolProperty::New(false) );
  segmentationNode->SetProperty( "layer", IntProperty::New(10) );
  segmentationNode->SetProperty( "levelwindow", LevelWindowProperty::New( LevelWindow(0.5, 1) ) );
  segmentationNode->SetProperty( "opacity", FloatProperty::New(0.3) );
  segmentationNode->SetProperty( "segmentation", BoolProperty::New(true) );
  segmentationNode->SetProperty( "reslice interpolation", VtkResliceInterpolationProperty::New() ); // otherwise -> segmentation appears in 2 slices sometimes (only visual effect, not different data)
  segmentationNode->SetProperty( "showVolume", BoolProperty::New( false ) );

  return segmentationNode;
}

<|endoftext|>


<commit_before>// stdafx.cpp : source file that includes just the standard includes
// thrededMatrixMult.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
<commit_msg>removed vs dependecy<commit_after><|endoftext|>


<commit_before>Bool_t ProcessOutputCheb(TString filesToProcess, Int_t startRun, Int_t endRun, const char* ocdbStorage, Bool_t corr=kTRUE) {

  // macro that process a list of files (xml or txt) to produce then the
  // OCDB entry for the TPC SP Distortion calibration; inspired by
  // AliAnalysisAlien::MergeOutput for simplicity

  gROOT->LoadMacro("$ALICE_PHYSICS/PWGPP/TPC/CalibMacros/CreateCorrMapObj.C");
  //gROOT->LoadMacro("CreateCorrMapObj.C");

  Bool_t isGrid = kTRUE;
  TObjArray *listoffiles = new TObjArray();

  if (filesToProcess.Contains(".xml")) {
    // Merge files pointed by the xml
    TGridCollection *coll = (TGridCollection*)gROOT->ProcessLine(Form("TAlienCollection::Open(\"%s\");", filesToProcess.Data()));
    if (!coll) {
      ::Error("ProcessOutput", "Input XML collection empty.");
      return kFALSE;
    }
    coll->Print();
    // Iterate grid collection
    while (coll->Next()) {
      TString fname = coll->GetTURL();
      Printf("fname = %s", fname.Data());
      listoffiles->Add(new TNamed(fname.Data(),""));
    }
  }

  else if (filesToProcess.Contains(".txt")) {
    TString line;
    ifstream in;
    in.open(filesToProcess);
    if (in.fail()) {
      ::Error("ProcessOutput", "File %s cannot be opened. Processing stopped." ,filesToProcess.Data());
      return kTRUE;
    }
    Int_t nfiles = 0;
    while (in.good()) {
      in >> line;
      if (line.IsNull()) continue;
      if (!line.Contains("alien:")) isGrid = kFALSE;
      nfiles++;
      listoffiles->Add(new TNamed(line.Data(),""));
    }
    in.close();
    if (!nfiles) {
      ::Error("ProcessOutput","Input file %s contains no files to be processed\n", filesToProcess.Data());
      delete listoffiles;
      return kFALSE;
    }
  }

  if (!listoffiles->GetEntries()) {
    ::Error("ProcessOutput","No files to process\n");
    delete listoffiles;
    return kFALSE;
  }

  if (startRun != endRun) {
    Printf("The processing now is only run-level, please check again!");
    return kFALSE;
  }

  Int_t run = startRun;
  TObject *nextfile;
  TString snextfile;
  TIter next(listoffiles);
  TObjArray* a = new TObjArray();
  a->SetOwner(kTRUE);

  Int_t lowStatJobs = 0;
  Int_t nJobs = 0;
  while (nextfile=next()) {
    snextfile = nextfile->GetName();
    Printf("opening file %s", snextfile.Data());
    if (isGrid) TGrid::Connect("alien://");
    AliTPCDcalibRes* dcalibRes = AliTPCDcalibRes::Load(snextfile.Data());
    if (!dcalibRes) {
      ::Error("ProcessOutput","Did not find calib object in %s, job Killed",snextfile.Data());
      exit(1);
    }
    int ntrUse = dcalibRes->GetNTracksUsed();
    int ntrMin = dcalibRes->GetMinTrackToUse();
    if (ntrUse<ntrMin) {
      ::Error("ProcessOutput","Low stat:%d tracks used (min: %d) in %s",ntrUse,ntrMin,snextfile.Data());
      lowStatJobs++;
    }
    else {
      ::Info("ProcessOutput","stat is OK :%d tracks used (min: %d) in %s",ntrUse,ntrMin,snextfile.Data());
    }
    AliTPCChebCorr* c = corr ? dcalibRes->GetChebCorrObject() : dcalibRes->GetChebDistObject();
    if (!c) {
      ::Error("ProcessOutput","Did not find %s Cheb.parm in %s",corr ? "Correction":"Distortion" ,snextfile.Data());
      exit(1);
    }
    a->Add(c);
    nJobs++;
  }
  if (lowStatJobs) {
    ::Error("ProcessOutput","%d out of %d timebins have low stat, will not update OCDB",lowStatJobs,nJobs);
  }
  else {
    a->Print();
    CreateCorrMapObjTime(a, startRun, endRun, ocdbStorage);
  }
  delete a;
  delete listoffiles;

  return kTRUE;

}
<commit_msg>Min tracks to allow ocdb object creation can be overridden by env.var.<commit_after>Bool_t ProcessOutputCheb(TString filesToProcess, Int_t startRun, Int_t endRun, const char* ocdbStorage, Bool_t corr=kTRUE) {

  // macro that process a list of files (xml or txt) to produce then the
  // OCDB entry for the TPC SP Distortion calibration; inspired by
  // AliAnalysisAlien::MergeOutput for simplicity

  gROOT->LoadMacro("$ALICE_PHYSICS/PWGPP/TPC/CalibMacros/CreateCorrMapObj.C");
  //gROOT->LoadMacro("CreateCorrMapObj.C");

  Bool_t isGrid = kTRUE;
  TObjArray *listoffiles = new TObjArray();

  int ntrminUser = -1;
  TString ntrminUserS = gSystem->Getenv("distMinTracks");
  if (!ntrminUserS.IsNull() && (ntrminUser=ntrminUserS.Atoi())>0) {
    ::Info("ProcessOutput","User provided min tracks to validate object: %d",ntrminUser);
  }

  if (filesToProcess.Contains(".xml")) {
    // Merge files pointed by the xml
    TGridCollection *coll = (TGridCollection*)gROOT->ProcessLine(Form("TAlienCollection::Open(\"%s\");", filesToProcess.Data()));
    if (!coll) {
      ::Error("ProcessOutput", "Input XML collection empty.");
      return kFALSE;
    }
    coll->Print();
    // Iterate grid collection
    while (coll->Next()) {
      TString fname = coll->GetTURL();
      Printf("fname = %s", fname.Data());
      listoffiles->Add(new TNamed(fname.Data(),""));
    }
  }

  else if (filesToProcess.Contains(".txt")) {
    TString line;
    ifstream in;
    in.open(filesToProcess);
    if (in.fail()) {
      ::Error("ProcessOutput", "File %s cannot be opened. Processing stopped." ,filesToProcess.Data());
      return kTRUE;
    }
    Int_t nfiles = 0;
    while (in.good()) {
      in >> line;
      if (line.IsNull()) continue;
      if (!line.Contains("alien:")) isGrid = kFALSE;
      nfiles++;
      listoffiles->Add(new TNamed(line.Data(),""));
    }
    in.close();
    if (!nfiles) {
      ::Error("ProcessOutput","Input file %s contains no files to be processed\n", filesToProcess.Data());
      delete listoffiles;
      return kFALSE;
    }
  }

  if (!listoffiles->GetEntries()) {
    ::Error("ProcessOutput","No files to process\n");
    delete listoffiles;
    return kFALSE;
  }

  if (startRun != endRun) {
    Printf("The processing now is only run-level, please check again!");
    return kFALSE;
  }

  Int_t run = startRun;
  TObject *nextfile;
  TString snextfile;
  TIter next(listoffiles);
  TObjArray* a = new TObjArray();
  a->SetOwner(kTRUE);

  Int_t lowStatJobs = 0;
  Int_t nJobs = 0;
  while (nextfile=next()) {
    snextfile = nextfile->GetName();
    Printf("opening file %s", snextfile.Data());
    if (isGrid) TGrid::Connect("alien://");
    AliTPCDcalibRes* dcalibRes = AliTPCDcalibRes::Load(snextfile.Data());
    if (!dcalibRes) {
      ::Error("ProcessOutput","Did not find calib object in %s, job Killed",snextfile.Data());
      exit(1);
    }
    int ntrUse = dcalibRes->GetNTracksUsed();
    int ntrMin = dcalibRes->GetMinTrackToUse();
    if (ntrminUser>0) ntrMin = ntrminUser;
    if (ntrUse<ntrMin) {
      ::Error("ProcessOutput","Low stat:%d tracks used (min: %d) in %s",ntrUse,ntrMin,snextfile.Data());
      lowStatJobs++;
    }
    else {
      ::Info("ProcessOutput","stat is OK :%d tracks used (min: %d) in %s",ntrUse,ntrMin,snextfile.Data());
    }
    AliTPCChebCorr* c = corr ? dcalibRes->GetChebCorrObject() : dcalibRes->GetChebDistObject();
    if (!c) {
      ::Error("ProcessOutput","Did not find %s Cheb.parm in %s",corr ? "Correction":"Distortion" ,snextfile.Data());
      exit(1);
    }
    a->Add(c);
    nJobs++;
  }
  if (lowStatJobs) {
    ::Error("ProcessOutput","%d out of %d timebins have low stat, will not update OCDB",lowStatJobs,nJobs);
  }
  else {
    a->Print();
    CreateCorrMapObjTime(a, startRun, endRun, ocdbStorage);
  }
  delete a;
  delete listoffiles;

  return kTRUE;

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: kdevcllayer.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 01:38:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"

#ifndef KDEVCLLAYER_HXX_
#include "kdevcllayer.hxx"
#endif

#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_PROPERTYINFO_HPP_
#include <com/sun/star/configuration/backend/PropertyInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XLAYERCONTENTDESCIBER_HPP_
#include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#ifndef INCLUDED_VCL_KDE_HEADERS_H
#include <vcl/kde_headers.h>
#endif

//==============================================================================

KDEVCLLayer::KDEVCLLayer(const uno::Reference<uno::XComponentContext>& xContext)
{
    //Create instance of LayerContentDescriber Service
    rtl::OUString const k_sLayerDescriberService(RTL_CONSTASCII_USTRINGPARAM(
        "com.sun.star.comp.configuration.backend.LayerDescriber"));

    typedef uno::Reference<backend::XLayerContentDescriber> LayerDescriber;
    uno::Reference< lang::XMultiComponentFactory > xServiceManager = xContext->getServiceManager();
    if( xServiceManager.is() )
    {
        m_xLayerContentDescriber = LayerDescriber::query(
            xServiceManager->createInstanceWithContext(k_sLayerDescriberService, xContext));
    }
    else
    {
        OSL_TRACE("Could not retrieve ServiceManager");
    }
}

//------------------------------------------------------------------------------

void SAL_CALL KDEVCLLayer::readData( const uno::Reference<backend::XLayerHandler>& xHandler)
    throw ( backend::MalformedDataException, lang::NullPointerException,
            lang::WrappedTargetException, uno::RuntimeException)
{
    if( ! m_xLayerContentDescriber.is() )
    {
        throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
            "Could not create com.sun.star.configuration.backend.LayerContentDescriber Service"
        ) ), static_cast < backend::XLayer * > (this) );
    }

    uno::Sequence<backend::PropertyInfo> aPropInfoList(1);

/*
   Commenting out, does not make much sense without an accessibility bridge
===========================================================================
#if defined(QT_ACCESSIBILITY_SUPPORT)
// Accessibility tools under Qt for UNIX are available starting with Qt 4.0
    int nVersionMajor = 0;
    const char *q = qVersion();     // "3.1.0" for example
    while ('0' <= *q && *q <= '9')
        nVersionMajor = nVersionMajor * 10 + *q++ - '0';
    sal_Bool ATToolSupport = (sal_Bool) (nVersionMajor >= 4);
#else
    sal_Bool ATToolSupport = sal_False;
#endif
===========================================================================
   End of commented out section
*/  sal_Bool ATToolSupport = sal_False;

    aPropInfoList[0].Name = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.VCL/Settings/Accessibility/EnableATToolSupport") );
    aPropInfoList[0].Type = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM( "string" ) );
    aPropInfoList[0].Protected = sal_False;
    aPropInfoList[0].Value = uno::makeAny( rtl::OUString::valueOf( ATToolSupport ) );

    m_xLayerContentDescriber->describeLayer(xHandler, aPropInfoList);
}

//------------------------------------------------------------------------------

rtl::OUString SAL_CALL KDEVCLLayer::getTimestamp(void)
    throw (uno::RuntimeException)
{
    // Return the value as timestamp to avoid regenerating the binary cache
    // on each office launch.

    ::rtl::OUString sTimeStamp(
                RTL_CONSTASCII_USTRINGPARAM( "FALSE" ) );

    return sTimeStamp;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.4.122); FILE MERGED 2008/04/01 15:40:12 thb 1.4.122.3: #i85898# Stripping all external header guards 2008/04/01 12:41:10 thb 1.4.122.2: #i85898# Stripping all external header guards 2008/03/31 13:17:07 rt 1.4.122.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: kdevcllayer.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"
#include "kdevcllayer.hxx"
#include <com/sun/star/configuration/backend/PropertyInfo.hpp>
#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XLAYERCONTENTDESCIBER_HPP_
#include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>
#endif
#include <com/sun/star/uno/Sequence.hxx>
#include <vcl/kde_headers.h>

//==============================================================================

KDEVCLLayer::KDEVCLLayer(const uno::Reference<uno::XComponentContext>& xContext)
{
    //Create instance of LayerContentDescriber Service
    rtl::OUString const k_sLayerDescriberService(RTL_CONSTASCII_USTRINGPARAM(
        "com.sun.star.comp.configuration.backend.LayerDescriber"));

    typedef uno::Reference<backend::XLayerContentDescriber> LayerDescriber;
    uno::Reference< lang::XMultiComponentFactory > xServiceManager = xContext->getServiceManager();
    if( xServiceManager.is() )
    {
        m_xLayerContentDescriber = LayerDescriber::query(
            xServiceManager->createInstanceWithContext(k_sLayerDescriberService, xContext));
    }
    else
    {
        OSL_TRACE("Could not retrieve ServiceManager");
    }
}

//------------------------------------------------------------------------------

void SAL_CALL KDEVCLLayer::readData( const uno::Reference<backend::XLayerHandler>& xHandler)
    throw ( backend::MalformedDataException, lang::NullPointerException,
            lang::WrappedTargetException, uno::RuntimeException)
{
    if( ! m_xLayerContentDescriber.is() )
    {
        throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
            "Could not create com.sun.star.configuration.backend.LayerContentDescriber Service"
        ) ), static_cast < backend::XLayer * > (this) );
    }

    uno::Sequence<backend::PropertyInfo> aPropInfoList(1);

/*
   Commenting out, does not make much sense without an accessibility bridge
===========================================================================
#if defined(QT_ACCESSIBILITY_SUPPORT)
// Accessibility tools under Qt for UNIX are available starting with Qt 4.0
    int nVersionMajor = 0;
    const char *q = qVersion();     // "3.1.0" for example
    while ('0' <= *q && *q <= '9')
        nVersionMajor = nVersionMajor * 10 + *q++ - '0';
    sal_Bool ATToolSupport = (sal_Bool) (nVersionMajor >= 4);
#else
    sal_Bool ATToolSupport = sal_False;
#endif
===========================================================================
   End of commented out section
*/  sal_Bool ATToolSupport = sal_False;

    aPropInfoList[0].Name = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.VCL/Settings/Accessibility/EnableATToolSupport") );
    aPropInfoList[0].Type = rtl::OUString(
        RTL_CONSTASCII_USTRINGPARAM( "string" ) );
    aPropInfoList[0].Protected = sal_False;
    aPropInfoList[0].Value = uno::makeAny( rtl::OUString::valueOf( ATToolSupport ) );

    m_xLayerContentDescriber->describeLayer(xHandler, aPropInfoList);
}

//------------------------------------------------------------------------------

rtl::OUString SAL_CALL KDEVCLLayer::getTimestamp(void)
    throw (uno::RuntimeException)
{
    // Return the value as timestamp to avoid regenerating the binary cache
    // on each office launch.

    ::rtl::OUString sTimeStamp(
                RTL_CONSTASCII_USTRINGPARAM( "FALSE" ) );

    return sTimeStamp;
}
<|endoftext|>