<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "value_codec.h"
#include "tensor_spec.h"
#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/typify.h>

namespace vespalib::eval {

namespace {

using CellType = ValueType::CellType;
using IndexList = std::vector<size_t>;

constexpr uint32_t DOUBLE_CELL_TYPE = 0;
constexpr uint32_t FLOAT_CELL_TYPE = 1;

inline uint32_t cell_type_to_id(CellType cell_type) {
    switch (cell_type) {
    case CellType::DOUBLE: return DOUBLE_CELL_TYPE;
    case CellType::FLOAT: return FLOAT_CELL_TYPE;
    }
    abort();
}

inline CellType id_to_cell_type(uint32_t id) {
    switch (id) {
    case DOUBLE_CELL_TYPE: return CellType::DOUBLE;
    case FLOAT_CELL_TYPE: return CellType::FLOAT;
    }
    abort();
}

/**
 * Meta information about how a type can be decomposed into mapped and
 * indexed dimensions and also how large each block is. A block is a
 * dense-subspace consisting of all indexed dimensions that is
 * uniquely specified by the labels of all mapped dimensions.
 **/
struct TypeMeta {
    IndexList mapped;
    IndexList indexed;
    size_t block_size;
    CellType cell_type;
    explicit TypeMeta(const ValueType &type)
        : mapped(),
          indexed(),
          block_size(1),
          cell_type(type.cell_type())
    {
        for (size_t i = 0; i < type.dimensions().size(); ++i) {
            const auto &dimension = type.dimensions()[i];
            if (dimension.is_mapped()) {
                mapped.push_back(i);
            } else {
                block_size *= dimension.size;
                indexed.push_back(i);
            }
        }
    }
    ~TypeMeta() {}
};

struct Format {
    bool     is_sparse;
    bool     is_dense;
    bool     with_cell_type;
    uint32_t tag;
    explicit Format(const TypeMeta &meta)
        : is_sparse(meta.mapped.size() > 0),
          is_dense((meta.indexed.size() > 0) || !is_sparse),
          with_cell_type(meta.cell_type != CellType::DOUBLE),
          tag((is_sparse ? 0x1 : 0) | (is_dense ? 0x2 : 0) | (with_cell_type ? 0x4 : 0)) {}
    explicit Format(uint32_t tag_in)
        : is_sparse((tag_in & 0x1) != 0),
          is_dense((tag_in & 0x2) != 0),
          with_cell_type((tag_in & 0x4) != 0),
          tag(tag_in) {}
    ~Format() {}
};

void maybe_encode_cell_type(nbostream &output, const Format &format, const TypeMeta &meta) {
    if (format.with_cell_type) {
        output.putInt1_4Bytes(cell_type_to_id(meta.cell_type));
    }
}

void encode_type(nbostream &output, const Format &format, const ValueType &type, const TypeMeta &meta) {
    maybe_encode_cell_type(output, format, meta);
    if (format.is_sparse) {
        output.putInt1_4Bytes(meta.mapped.size());
        for (size_t idx: meta.mapped) {
            output.writeSmallString(type.dimensions()[idx].name);
        }
    }
    if (format.is_dense) {
        output.putInt1_4Bytes(meta.indexed.size());
        for (size_t idx: meta.indexed) {
            output.writeSmallString(type.dimensions()[idx].name);
            output.putInt1_4Bytes(type.dimensions()[idx].size);
        }
    }
}

void maybe_encode_num_blocks(nbostream &output, const TypeMeta &meta, size_t num_blocks) {
    if ((meta.mapped.size() > 0)) {
        output.putInt1_4Bytes(num_blocks);
    }
}

CellType maybe_decode_cell_type(nbostream &input, const Format &format) {
    if (format.with_cell_type) {
        return id_to_cell_type(input.getInt1_4Bytes());
    }
    return CellType::DOUBLE;
}

ValueType decode_type(nbostream &input, const Format &format) {
    CellType cell_type = maybe_decode_cell_type(input, format);
    std::vector<ValueType::Dimension> dim_list;
    if (format.is_sparse) {
        size_t cnt = input.getInt1_4Bytes();
        for (size_t i = 0; i < cnt; ++i) {
            vespalib::string name;
            input.readSmallString(name);
            dim_list.emplace_back(name);
        }
    }
    if (format.is_dense) {
        size_t cnt = input.getInt1_4Bytes();
        for (size_t i = 0; i < cnt; ++i) {
            vespalib::string name;
            input.readSmallString(name);
            dim_list.emplace_back(name, input.getInt1_4Bytes());
        }
    }
    return ValueType::tensor_type(std::move(dim_list), cell_type);
}

size_t maybe_decode_num_blocks(nbostream &input, const TypeMeta &meta, const Format &format) {
    if ((meta.mapped.size() > 0) || !format.is_dense) {
        return input.getInt1_4Bytes();
    }
    return 1;
}

void encode_mapped_labels(nbostream &output, size_t num_mapped_dims, const std::vector<vespalib::stringref> &addr) {
    for (size_t i = 0; i < num_mapped_dims; ++i) {
        output.writeSmallString(addr[i]);
    }
}

void decode_mapped_labels(nbostream &input, size_t num_mapped_dims, std::vector<vespalib::stringref> &addr) {
    for (size_t i = 0; i < num_mapped_dims; ++i) {
        size_t strSize = input.getInt1_4Bytes();
        addr[i] = vespalib::stringref(input.peek(), strSize);
        input.adjustReadPos(strSize);
    }
}

template<typename T>
void decode_cells(nbostream &input, size_t num_cells, ArrayRef<T> dst)
{
    T value;
    for (size_t i = 0; i < num_cells; ++i) {
        input >> value;
        dst[i] = value;
    }
}

struct DecodeState {
    const ValueType &type;
    const size_t block_size;
    const size_t num_blocks;
    const size_t num_mapped_dims;
};

struct ContentDecoder {
    template<typename T>
    static std::unique_ptr<Value> invoke(nbostream &input, const DecodeState &state, const ValueBuilderFactory &factory) {
        std::vector<vespalib::stringref> address(state.num_mapped_dims);
        auto builder = factory.create_value_builder<T>(state.type, state.num_mapped_dims, state.block_size, state.num_blocks);
        for (size_t i = 0; i < state.num_blocks; ++i) {
            decode_mapped_labels(input, state.num_mapped_dims, address);
            auto block_cells = builder->add_subspace(address);
            decode_cells(input, state.block_size, block_cells);
        }
        return builder->build(std::move(builder));
    }
};

struct CreateValueFromTensorSpec {
    template <typename T> static std::unique_ptr<Value> invoke(const ValueType &type, const TensorSpec &spec, const ValueBuilderFactory &factory) {
        using SparseKey = std::vector<vespalib::stringref>;
        using DenseMap = std::map<size_t,T>;
        std::map<SparseKey,DenseMap> map;
        for (const auto &entry: spec.cells()) {
            SparseKey sparse_key;
            size_t dense_key = 0;
            for (const auto &dim: type.dimensions()) {
                auto pos = entry.first.find(dim.name);
                assert(pos != entry.first.end());
                assert(pos->second.is_mapped() == dim.is_mapped());
                if (dim.is_mapped()) {
                    sparse_key.emplace_back(pos->second.name);
                } else {
                    dense_key = (dense_key * dim.size) + pos->second.index;
                }
            }
            map[sparse_key][dense_key] = entry.second;
        }
        // if spec is missing the required dense space, add it here:
        if (map.empty() && type.count_mapped_dimensions() == 0) {
            map[{}][0] = 0;
        }
        auto builder = factory.create_value_builder<T>(type, type.count_mapped_dimensions(), type.dense_subspace_size(), map.size());
        for (const auto &entry: map) {
            auto subspace = builder->add_subspace(entry.first);
            for (const auto &cell: entry.second) {
                subspace[cell.first] = cell.second;
            }
        }
        return builder->build(std::move(builder));
    }
};

struct CreateTensorSpecFromValue {
    template <typename T> static TensorSpec invoke(const Value &value) {
        auto cells = value.cells().typify<T>();
        TensorSpec spec(value.type().to_spec());
        size_t subspace_id = 0;
        size_t subspace_size = value.type().dense_subspace_size();
        std::vector<vespalib::stringref> labels(value.type().count_mapped_dimensions());
        std::vector<vespalib::stringref*> label_refs;
        for (auto &label: labels) {
            label_refs.push_back(&label);
        }
        auto view = value.index().create_view({});
        view->lookup({});
        while (view->next_result(label_refs, subspace_id)) {
            size_t label_idx = 0;
            TensorSpec::Address addr;
            for (const auto &dim: value.type().dimensions()) {
                if (dim.is_mapped()) {
                    addr.emplace(dim.name, labels[label_idx++]);
                }
            }
            for (size_t i = 0; i < subspace_size; ++i) {
                size_t dense_key = i;
                for (auto dim = value.type().dimensions().rbegin();
                     dim != value.type().dimensions().rend(); ++dim)
                {
                    if (dim->is_indexed()) {
                        size_t label = dense_key % dim->size;
                        addr.emplace(dim->name, label).first->second = TensorSpec::Label(label);
                        dense_key /= dim->size;
                    }
                }
                spec.add(addr, cells[(subspace_size * subspace_id) + i]);
            }
        }
        return spec;
    }
};

} // namespace <unnamed>

void new_encode(const Value &value, nbostream &output) {
    TypeMeta meta(value.type());
    Format format(meta);
    output.putInt1_4Bytes(format.tag);
    encode_type(output, format, value.type(), meta);
    maybe_encode_num_blocks(output, meta, value.cells().size / meta.block_size);
    std::vector<vespalib::stringref> address(meta.mapped.size());
    std::vector<vespalib::stringref*> a_refs(meta.mapped.size());
    for (size_t i = 0; i < meta.mapped.size(); ++i) {
        a_refs[i] = &address[i];
    }
    auto view = value.index().create_view({});
    view->lookup({});
    size_t subspace;
    while (view->next_result(a_refs, subspace)) {
        encode_mapped_labels(output, meta.mapped.size(), address);
        if (meta.cell_type == CellType::FLOAT) {
            auto iter = value.cells().typify<float>().begin();
            iter += (subspace * meta.block_size);
            for (size_t i = 0; i < meta.block_size; ++i) {
                output << (float) *iter++;
            }
        } else {
            auto iter = value.cells().typify<double>().begin();
            iter += (subspace * meta.block_size);
            for (size_t i = 0; i < meta.block_size; ++i) {
                output << *iter++;
            }
        }
    }
}

std::unique_ptr<Value> new_decode(nbostream &input, const ValueBuilderFactory &factory) {
    Format format(input.getInt1_4Bytes());
    ValueType type = decode_type(input, format);
    TypeMeta meta(type);
    const size_t num_blocks = maybe_decode_num_blocks(input, meta, format);
    DecodeState state{type, meta.block_size, num_blocks, meta.mapped.size()};
    return typify_invoke<1,TypifyCellType,ContentDecoder>(meta.cell_type, input, state, factory);
}

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

std::unique_ptr<Value> value_from_spec(const TensorSpec &spec, const ValueBuilderFactory &factory) {
    ValueType type = ValueType::from_spec(spec.type());
    assert(!type.is_error());
    return typify_invoke<1,TypifyCellType,CreateValueFromTensorSpec>(type.cell_type(), type, spec, factory);
}

TensorSpec spec_from_value(const Value &value) {
    return typify_invoke<1,TypifyCellType,CreateTensorSpecFromValue>(value.type().cell_type(), value);
}

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

} // namespace
<commit_msg>simplify value_codec some<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "value_codec.h"
#include "tensor_spec.h"
#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/typify.h>

namespace vespalib::eval {

namespace {

using CellType = ValueType::CellType;
using IndexList = std::vector<size_t>;

constexpr uint32_t DOUBLE_CELL_TYPE = 0;
constexpr uint32_t FLOAT_CELL_TYPE = 1;

inline uint32_t cell_type_to_id(CellType cell_type) {
    switch (cell_type) {
    case CellType::DOUBLE: return DOUBLE_CELL_TYPE;
    case CellType::FLOAT: return FLOAT_CELL_TYPE;
    }
    abort();
}

inline CellType id_to_cell_type(uint32_t id) {
    switch (id) {
    case DOUBLE_CELL_TYPE: return CellType::DOUBLE;
    case FLOAT_CELL_TYPE: return CellType::FLOAT;
    }
    abort();
}

/**
 * Meta information about how a type can be decomposed into mapped and
 * indexed dimensions and also how large each block is. A block is a
 * dense-subspace consisting of all indexed dimensions that is
 * uniquely specified by the labels of all mapped dimensions.
 **/
struct TypeMeta {
    IndexList mapped;
    IndexList indexed;
    CellType cell_type;
    explicit TypeMeta(const ValueType &type)
        : mapped(),
          indexed(),
          cell_type(type.cell_type())
    {
        for (size_t i = 0; i < type.dimensions().size(); ++i) {
            const auto &dimension = type.dimensions()[i];
            if (dimension.is_mapped()) {
                mapped.push_back(i);
            } else {
                indexed.push_back(i);
            }
        }
    }
    ~TypeMeta() {}
};

struct Format {
    bool     is_sparse;
    bool     is_dense;
    bool     with_cell_type;
    uint32_t tag;
    explicit Format(const TypeMeta &meta)
        : is_sparse(meta.mapped.size() > 0),
          is_dense((meta.indexed.size() > 0) || !is_sparse),
          with_cell_type(meta.cell_type != CellType::DOUBLE),
          tag((is_sparse ? 0x1 : 0) | (is_dense ? 0x2 : 0) | (with_cell_type ? 0x4 : 0)) {}
    explicit Format(uint32_t tag_in)
        : is_sparse((tag_in & 0x1) != 0),
          is_dense((tag_in & 0x2) != 0),
          with_cell_type((tag_in & 0x4) != 0),
          tag(tag_in) {}
    ~Format() {}
};

void maybe_encode_cell_type(nbostream &output, const Format &format, const TypeMeta &meta) {
    if (format.with_cell_type) {
        output.putInt1_4Bytes(cell_type_to_id(meta.cell_type));
    }
}

void encode_type(nbostream &output, const Format &format, const ValueType &type, const TypeMeta &meta) {
    maybe_encode_cell_type(output, format, meta);
    if (format.is_sparse) {
        output.putInt1_4Bytes(type.count_mapped_dimensions());
        for (size_t idx: meta.mapped) {
            output.writeSmallString(type.dimensions()[idx].name);
        }
    }
    if (format.is_dense) {
        output.putInt1_4Bytes(meta.indexed.size());
        for (size_t idx: meta.indexed) {
            output.writeSmallString(type.dimensions()[idx].name);
            output.putInt1_4Bytes(type.dimensions()[idx].size);
        }
    }
}

void maybe_encode_num_blocks(nbostream &output, bool has_mapped_dims, size_t num_blocks) {
    if (has_mapped_dims) {
        output.putInt1_4Bytes(num_blocks);
    }
}

CellType maybe_decode_cell_type(nbostream &input, const Format &format) {
    if (format.with_cell_type) {
        return id_to_cell_type(input.getInt1_4Bytes());
    }
    return CellType::DOUBLE;
}

ValueType decode_type(nbostream &input, const Format &format) {
    CellType cell_type = maybe_decode_cell_type(input, format);
    std::vector<ValueType::Dimension> dim_list;
    if (format.is_sparse) {
        size_t cnt = input.getInt1_4Bytes();
        for (size_t i = 0; i < cnt; ++i) {
            vespalib::string name;
            input.readSmallString(name);
            dim_list.emplace_back(name);
        }
    }
    if (format.is_dense) {
        size_t cnt = input.getInt1_4Bytes();
        for (size_t i = 0; i < cnt; ++i) {
            vespalib::string name;
            input.readSmallString(name);
            dim_list.emplace_back(name, input.getInt1_4Bytes());
        }
    }
    return ValueType::tensor_type(std::move(dim_list), cell_type);
}

size_t maybe_decode_num_blocks(nbostream &input, bool has_mapped_dims, const Format &format) {
    if (has_mapped_dims || !format.is_dense) {
        return input.getInt1_4Bytes();
    }
    return 1;
}

void encode_mapped_labels(nbostream &output, size_t num_mapped_dims, const std::vector<vespalib::stringref> &addr) {
    for (size_t i = 0; i < num_mapped_dims; ++i) {
        output.writeSmallString(addr[i]);
    }
}

void decode_mapped_labels(nbostream &input, size_t num_mapped_dims, std::vector<vespalib::stringref> &addr) {
    for (size_t i = 0; i < num_mapped_dims; ++i) {
        size_t strSize = input.getInt1_4Bytes();
        addr[i] = vespalib::stringref(input.peek(), strSize);
        input.adjustReadPos(strSize);
    }
}

template<typename T>
void decode_cells(nbostream &input, size_t num_cells, ArrayRef<T> dst)
{
    T value;
    for (size_t i = 0; i < num_cells; ++i) {
        input >> value;
        dst[i] = value;
    }
}

struct DecodeState {
    const ValueType &type;
    const size_t subspace_size;
    const size_t num_blocks;
    const size_t num_mapped_dims;
};

struct ContentDecoder {
    template<typename T>
    static std::unique_ptr<Value> invoke(nbostream &input, const DecodeState &state, const ValueBuilderFactory &factory) {
        std::vector<vespalib::stringref> address(state.num_mapped_dims);
        auto builder = factory.create_value_builder<T>(state.type, state.num_mapped_dims, state.subspace_size, state.num_blocks);
        for (size_t i = 0; i < state.num_blocks; ++i) {
            decode_mapped_labels(input, state.num_mapped_dims, address);
            auto block_cells = builder->add_subspace(address);
            decode_cells(input, state.subspace_size, block_cells);
        }
        return builder->build(std::move(builder));
    }
};

struct CreateValueFromTensorSpec {
    template <typename T> static std::unique_ptr<Value> invoke(const ValueType &type, const TensorSpec &spec, const ValueBuilderFactory &factory) {
        using SparseKey = std::vector<vespalib::stringref>;
        using DenseMap = std::map<size_t,T>;
        std::map<SparseKey,DenseMap> map;
        for (const auto &entry: spec.cells()) {
            SparseKey sparse_key;
            size_t dense_key = 0;
            for (const auto &dim: type.dimensions()) {
                auto pos = entry.first.find(dim.name);
                assert(pos != entry.first.end());
                assert(pos->second.is_mapped() == dim.is_mapped());
                if (dim.is_mapped()) {
                    sparse_key.emplace_back(pos->second.name);
                } else {
                    dense_key = (dense_key * dim.size) + pos->second.index;
                }
            }
            map[sparse_key][dense_key] = entry.second;
        }
        // if spec is missing the required dense space, add it here:
        if (map.empty() && type.count_mapped_dimensions() == 0) {
            map[{}][0] = 0;
        }
        auto builder = factory.create_value_builder<T>(type, type.count_mapped_dimensions(), type.dense_subspace_size(), map.size());
        for (const auto &entry: map) {
            auto subspace = builder->add_subspace(entry.first);
            for (const auto &cell: entry.second) {
                subspace[cell.first] = cell.second;
            }
        }
        return builder->build(std::move(builder));
    }
};

struct CreateTensorSpecFromValue {
    template <typename T> static TensorSpec invoke(const Value &value) {
        auto cells = value.cells().typify<T>();
        TensorSpec spec(value.type().to_spec());
        size_t subspace_id = 0;
        size_t subspace_size = value.type().dense_subspace_size();
        std::vector<vespalib::stringref> labels(value.type().count_mapped_dimensions());
        std::vector<vespalib::stringref*> label_refs;
        for (auto &label: labels) {
            label_refs.push_back(&label);
        }
        auto view = value.index().create_view({});
        view->lookup({});
        while (view->next_result(label_refs, subspace_id)) {
            size_t label_idx = 0;
            TensorSpec::Address addr;
            for (const auto &dim: value.type().dimensions()) {
                if (dim.is_mapped()) {
                    addr.emplace(dim.name, labels[label_idx++]);
                }
            }
            for (size_t i = 0; i < subspace_size; ++i) {
                size_t dense_key = i;
                for (auto dim = value.type().dimensions().rbegin();
                     dim != value.type().dimensions().rend(); ++dim)
                {
                    if (dim->is_indexed()) {
                        size_t label = dense_key % dim->size;
                        addr.emplace(dim->name, label).first->second = TensorSpec::Label(label);
                        dense_key /= dim->size;
                    }
                }
                spec.add(addr, cells[(subspace_size * subspace_id) + i]);
            }
        }
        return spec;
    }
};

} // namespace <unnamed>

void new_encode(const Value &value, nbostream &output) {
    TypeMeta meta(value.type());
    size_t num_mapped_dims = value.type().count_mapped_dimensions();
    size_t dense_subspace_size = value.type().dense_subspace_size();
    Format format(meta);
    output.putInt1_4Bytes(format.tag);
    encode_type(output, format, value.type(), meta);
    maybe_encode_num_blocks(output, (num_mapped_dims > 0), value.cells().size / dense_subspace_size);
    std::vector<vespalib::stringref> address(num_mapped_dims);
    std::vector<vespalib::stringref*> a_refs(num_mapped_dims);
    for (size_t i = 0; i < num_mapped_dims; ++i) {
        a_refs[i] = &address[i];
    }
    auto view = value.index().create_view({});
    view->lookup({});
    size_t subspace;
    while (view->next_result(a_refs, subspace)) {
        encode_mapped_labels(output, num_mapped_dims, address);
        if (meta.cell_type == CellType::FLOAT) {
            auto iter = value.cells().typify<float>().begin();
            iter += (subspace * dense_subspace_size);
            for (size_t i = 0; i < dense_subspace_size; ++i) {
                output << (float) *iter++;
            }
        } else {
            auto iter = value.cells().typify<double>().begin();
            iter += (subspace * dense_subspace_size);
            for (size_t i = 0; i < dense_subspace_size; ++i) {
                output << *iter++;
            }
        }
    }
}

std::unique_ptr<Value> new_decode(nbostream &input, const ValueBuilderFactory &factory) {
    Format format(input.getInt1_4Bytes());
    ValueType type = decode_type(input, format);
    size_t num_mapped_dims = type.count_mapped_dimensions();
    size_t dense_subspace_size = type.dense_subspace_size();
    TypeMeta meta(type);
    const size_t num_blocks = maybe_decode_num_blocks(input, (num_mapped_dims > 0), format);
    DecodeState state{type, dense_subspace_size, num_blocks, num_mapped_dims};
    return typify_invoke<1,TypifyCellType,ContentDecoder>(meta.cell_type, input, state, factory);
}

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

std::unique_ptr<Value> value_from_spec(const TensorSpec &spec, const ValueBuilderFactory &factory) {
    ValueType type = ValueType::from_spec(spec.type());
    assert(!type.is_error());
    return typify_invoke<1,TypifyCellType,CreateValueFromTensorSpec>(type.cell_type(), type, spec, factory);
}

TensorSpec spec_from_value(const Value &value) {
    return typify_invoke<1,TypifyCellType,CreateTensorSpecFromValue>(value.type().cell_type(), value);
}

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

} // namespace
<|endoftext|>


<commit_before>#ifndef AZIMUTH_ROTARY_HPP_INCLUDED
#define AZIMUTH_ROTARY_HPP_INCLUDED

/**
 @file azimuth_rotary.hpp
 @author François Becker

MIT License

Copyright (c) 2017 François Becker

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 "JuceHeader.h"

#include "math_float_constants.hpp"

/**
 @class AzimuthRotary
 A Juce rotary encoder that loops between 180° and -180° and uses the
 trigonometric convention: positive left.
 */
class AzimuthRotary
: public Slider
{
public:
    AzimuthRotary (const String& componentName)
    : Slider (componentName)
    {
        setDoubleClickReturnValue(true, 0.f);
        setSliderStyle (Slider::Rotary); // TODO: support Slider::RotaryHorizontalVerticalDrag;
        setRotaryParameters({M_PIf, 3.f * M_PIf, false});
    }
    double proportionOfLengthToValue (double proportion) override
    {
        return 1.0 - Slider::proportionOfLengthToValue(proportion);
    }
    double valueToProportionOfLength (double value) override
    {
        return 1.0 - Slider::valueToProportionOfLength(value);
    }
};

#endif
<commit_msg>Solved a potential compiler warning in AzimuthRotary<commit_after>#ifndef AZIMUTH_ROTARY_HPP_INCLUDED
#define AZIMUTH_ROTARY_HPP_INCLUDED

/**
 @file azimuth_rotary.hpp
 @author François Becker

MIT License

Copyright (c) 2017 François Becker

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 "JuceHeader.h"

#include "math_float_constants.hpp"

/**
 @class AzimuthRotary
 A Juce rotary encoder that loops between 180° and -180° and uses the
 trigonometric convention: positive left.
 */
class AzimuthRotary
: public Slider
{
public:
    AzimuthRotary (const String& componentName)
    : Slider (componentName)
    {
        setDoubleClickReturnValue(true, 0.);
        setSliderStyle (Slider::Rotary); // TODO: support Slider::RotaryHorizontalVerticalDrag;
        setRotaryParameters({M_PIf, 3.f * M_PIf, false});
    }
    double proportionOfLengthToValue (double proportion) override
    {
        return 1.0 - Slider::proportionOfLengthToValue(proportion);
    }
    double valueToProportionOfLength (double value) override
    {
        return 1.0 - Slider::valueToProportionOfLength(value);
    }
};

#endif
<|endoftext|>


<commit_before>#include <stdexcept>
#include <fstream>
#include <xorg/gtest/xorg-gtest.h>

#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>

#include "input-driver-test.h"

void InputDriverTest::StartServer() {
    server.Start();
    server.WaitForConnections();
    xorg::testing::Test::SetDisplayString(server.GetDisplayString());

    ASSERT_NO_FATAL_FAILURE(xorg::testing::Test::SetUp());

    int event_start;
    int error_start;

    ASSERT_TRUE(XQueryExtension(Display(), "XInputExtension", &xi2_opcode,
                &event_start, &error_start));

    int major = 2;
    int minor = 0;

    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));
}

void InputDriverTest::SetUpConfigAndLog(const std::string& param) {
    std::stringstream s;
    s << "/tmp/Xorg-" << param << ".log";
    server.SetOption("-logfile", s.str());

    s.str(std::string());
    s << "/tmp/" << param << ".conf";
    config.SetPath(s.str());

    config.AddDefaultScreenWithDriver();
    config.AddInputSection(param);
    config.WriteConfig();
    server.SetOption("-config", config.GetPath());
}

void InputDriverTest::SetUpEventListener() {
    failed = false;

    testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
    listeners.Append(this);
}

void InputDriverTest::SetUp() {
    SetUp("");
}

void InputDriverTest::SetUp(const std::string &param) {
    SetUpEventListener();
    SetUpConfigAndLog(param);
    StartServer();
}

void InputDriverTest::TearDown() {
    if (server.Pid() != -1)
        if (!server.Terminate(3000))
            server.Kill(3000);

    if (!Failed()) {
        config.RemoveConfig();
        server.RemoveLogFile();
    }

    testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
    listeners.Release(this);
}

void InputDriverTest::OnTestPartResult(const ::testing::TestPartResult &test_part_result) {
    failed = test_part_result.failed();
}

bool InputDriverTest::Failed() {
    return failed;
}
<commit_msg>The default devices should have Option CorePointer on<commit_after>#include <stdexcept>
#include <fstream>
#include <xorg/gtest/xorg-gtest.h>

#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>

#include "input-driver-test.h"

void InputDriverTest::StartServer() {
    server.Start();
    server.WaitForConnections();
    xorg::testing::Test::SetDisplayString(server.GetDisplayString());

    ASSERT_NO_FATAL_FAILURE(xorg::testing::Test::SetUp());

    int event_start;
    int error_start;

    ASSERT_TRUE(XQueryExtension(Display(), "XInputExtension", &xi2_opcode,
                &event_start, &error_start));

    int major = 2;
    int minor = 0;

    ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));
}

void InputDriverTest::SetUpConfigAndLog(const std::string& param) {
    std::stringstream s;
    s << "/tmp/Xorg-" << param << ".log";
    server.SetOption("-logfile", s.str());

    s.str(std::string());
    s << "/tmp/" << param << ".conf";
    config.SetPath(s.str());

    config.AddDefaultScreenWithDriver();
    config.AddInputSection(param, "--device--", "Option \"CorePointer\" \"on\"\n");
    config.WriteConfig();
    server.SetOption("-config", config.GetPath());
}

void InputDriverTest::SetUpEventListener() {
    failed = false;

    testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
    listeners.Append(this);
}

void InputDriverTest::SetUp() {
    SetUp("");
}

void InputDriverTest::SetUp(const std::string &param) {
    SetUpEventListener();
    SetUpConfigAndLog(param);
    StartServer();
}

void InputDriverTest::TearDown() {
    if (server.Pid() != -1)
        if (!server.Terminate(3000))
            server.Kill(3000);

    if (!Failed()) {
        config.RemoveConfig();
        server.RemoveLogFile();
    }

    testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
    listeners.Release(this);
}

void InputDriverTest::OnTestPartResult(const ::testing::TestPartResult &test_part_result) {
    failed = test_part_result.failed();
}

bool InputDriverTest::Failed() {
    return failed;
}
<|endoftext|>


<commit_before>
#pragma once

#include <cstdlib>
#include <string>

namespace principia {
namespace base {

#define STRINGIFY(X) #X
#define STRINGIFY_EXPANSION(X) STRINGIFY(X)

// See http://goo.gl/2EVxN4 for a partial overview of compiler detection and
// version macros.  We cannot use |COMPILER_MSVC| because it conflicts with
// a macro in the benchmark library, so the macros have obnoxiously long names.
// TODO(phl): See whether that |COMPILER_MSVC| macro can be removed from port.h.
#if defined(_MSC_VER) && defined(__clang__)
#define PRINCIPIA_COMPILER_CLANG_CL 1
char const* const CompilerName = "Clang-cl";
char const* const CompilerVersion = __VERSION__;
#elif defined(__clang__)
#define PRINCIPIA_COMPILER_CLANG 1
char const* const CompilerName = "Clang";
char const* const CompilerVersion = __VERSION__;
#elif defined(_MSC_VER)
#define PRINCIPIA_COMPILER_MSVC 1
char const* const CompilerName = "Microsoft Visual C++";
char const* const CompilerVersion = STRINGIFY_EXPANSION(_MSC_FULL_VER);
#elif defined(__ICC) || defined(__INTEL_COMPILER)
#define PRINCIPIA_COMPILER_ICC 1
char const* const CompilerName = "Intel C++ Compiler";
char const* const CompilerVersion = __VERSION__;
#elif defined(__GNUC__)
#define PRINCIPIA_COMPILER_GCC 1
char const* const CompilerName = "G++";
char const* const CompilerVersion = __VERSION__;
#else
#error "What is this, Borland C++?"
#endif

#if defined(__APPLE__)
#define OS_MACOSX 1
char const* const OperatingSystem = "OS X";
#elif defined(__linux__)
#define OS_LINUX 1
char const* const OperatingSystem = "Linux";
#elif defined(__FreeBSD__)
#define OS_FREEBSD 1
char const* const OperatingSystem = "FreeBSD";
#elif defined(_WIN32)
#define OS_WIN 1
char const* const OperatingSystem = "Windows";
#else
#error "Try OS/360."
#endif

#if defined(__i386) || defined(_M_IX86)
#define ARCH_CPU_X86_FAMILY 1
#define ARCH_CPU_X86 1
#define ARCH_CPU_32_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 1
char const* const Architecture = "x86";
#elif defined(_M_X64) || defined(__x86_64__)
#define ARCH_CPU_X86_FAMILY 1
#define ARCH_CPU_X86_64 1
#define ARCH_CPU_64_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 1
char const* const Architecture = "x86-64";
#else
#error "Have you tried a Cray-1?"
#endif

#if defined(CDECL)
#  error "CDECL already defined"
#else
// Architecture macros from http://goo.gl/ZypnO8.
// We use cdecl on x86, the calling convention is unambiguous on x86-64.
#  if ARCH_CPU_X86
#    if PRINCIPIA_COMPILER_CLANG ||  \
        PRINCIPIA_COMPILER_MSVC ||   \
        PRINCIPIA_COMPILER_CLANG_CL
#      define CDECL __cdecl
#    elif PRINCIPIA_COMPILER_ICC || PRINCIPIA_COMPILER_GCC
#      define CDECL __attribute__((cdecl))
#    else
#      error "Get a real compiler!"
#    endif
#  elif ARCH_CPU_X86_64
#    define CDECL
#  else
#    error "Have you tried a Cray-1?"
#  endif
#endif

// DLL-exported functions for interfacing with Platform Invocation Services.
#if defined(PRINCIPIA_DLL)
#  error "PRINCIPIA_DLL already defined"
#else
#  if OS_WIN
#    if PRINCIPIA_DLL_IMPORT
#      define PRINCIPIA_DLL __declspec(dllimport)
#    else
#      define PRINCIPIA_DLL __declspec(dllexport)
#    endif
#  else
#    define PRINCIPIA_DLL __attribute__((visibility("default")))
#  endif
#endif

// DLL-exported functions for isolated physics optimization.
#if defined(PHYSICS_DLL)
#  error "PHYSICS_DLL already defined"
#else
#  if OS_WIN
#    if PHYSICS_DLL_IMPORT
#      define PHYSICS_DLL __declspec(dllimport)
#      define PHYSICS_DLL_TEMPLATE_CLASS extern template class PHYSICS_DLL
#    else
#      define PHYSICS_DLL __declspec(dllexport)
#      define PHYSICS_DLL_TEMPLATE_CLASS template class PHYSICS_DLL
#    endif
#  else
#    define PHYSICS_DLL __attribute__((visibility("default")))
     // No isolated physics library on Linux or Macintosh at the moment.
#    define PHYSICS_DLL_TEMPLATE_CLASS template class PHYSICS_DLL
#  endif
#endif

// A function for use on control paths that don't return a value, typically
// because they end with a |LOG(FATAL)|.
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
[[noreturn]]
#elif PRINCIPIA_COMPILER_MSVC
__declspec(noreturn)
#elif PRINCIPIA_COMPILER_ICC
__attribute__((noreturn))
#else
#error "What compiler is this?"
#endif
inline void noreturn() { std::exit(0); }

// Used to force inlining.
#if PRINCIPIA_COMPILER_CLANG    ||  \
    PRINCIPIA_COMPILER_CLANG_CL ||  \
    PRINCIPIA_COMPILER_GCC
#  define FORCE_INLINE(specifiers) [[gnu::always_inline]] specifiers // NOLINT
#elif PRINCIPIA_COMPILER_MSVC
#  define FORCE_INLINE(specifiers) specifiers __forceinline
#elif PRINCIPIA_COMPILER_ICC
#  define FORCE_INLINE(specifiers) __attribute__((always_inline))
#else
#  error "What compiler is this?"
#endif

// Used to emit the function signature.
#if PRINCIPIA_COMPILER_CLANG    ||  \
    PRINCIPIA_COMPILER_CLANG_CL ||  \
    PRINCIPIA_COMPILER_GCC
#  define FUNCTION_SIGNATURE __PRETTY_FUNCTION__
#elif PRINCIPIA_COMPILER_MSVC
#  define FUNCTION_SIGNATURE __FUNCSIG__
#else
#  error "What compiler is this?"
#endif

// We assume that the processor is at least a Prescott since we only support
// 64-bit architectures.
#define PRINCIPIA_USE_SSE3_INTRINSICS !_DEBUG

// Thread-safety analysis.
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
#  define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#  define EXCLUDES(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#  define GUARDED_BY(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(__VA_ARGS__))
#  define REQUIRES(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#  define REQUIRES_SHARED(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#else
#  define EXCLUDES(x)
#  define GUARDED_BY(x)
#  define REQUIRES(x)
#  define REQUIRES_SHARED(x)
#endif

// Unicode.
#if OS_WIN
#  define UNICODE_PATH(x) u ## x
#else
#  define UNICODE_PATH(x) u8 ## x
#endif

// Mutex.
#if !OS_MACOSX
#  define HAS_SHARED_MUTEX 1
#endif

#define NAMED(expression) #expression << ": " << (expression)

// A macro to allow glog checking within C++11 constexpr code.  If |condition|
// is true, evaluates to |expression|.  Otherwise, results in a CHECK failure at
// runtime and a compilation error due to a call to non-constexpr code at
// compile time.
// NOTE(egg): in the failure case, the |LOG(FATAL)| is wrapped in a lambda.  The
// reason is that |LOG(FATAL)| constructs a |google::LogMessageFatal|, and
// |google::LogMessage::Fail()| is called in its destructor.  As a temporary,
// the |google::LogMessageFatal| is destroyed as the last step in evaluating the
// enclosing full-expression.  If we simply used the comma operator, the entire
// ternary |((condition) ? (expression) : (CHECK(condition), (expression)))|
// would be part of the enclosing full-expression, so that |expression| would
// get evaluated before the |CHECK| failure, possibly triggering all sorts of
// terrible UB or other checks (|DateDeathTest| provides a couple of examples).
// With the lambda, the full-expression forms the expression statement
// |LOG(FATAL) << "Check failed: " #condition " ";|, so that failure occurs
// before we return from the lambda's function call operator, and |expression|
// is never evaluated.  We do not use |CHECK| because that would require
// capture, but this should produce the same output.
#define CHECKING(condition, expression)                                      \
  ((condition) ? (expression)                                                \
               : (([] { LOG(FATAL) << "Check failed: " #condition " "; })(), \
                  (expression)))
// Needed to circumvent lint warnings in constexpr function where CHECK_LT and
// friends cannot be used.
#define CONSTEXPR_CHECK(condition) CHECK(condition)

// Clang for some reason doesn't like FP arithmetic that yields infinities in
// constexpr code (MSVC and GCC are fine with that).
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
#  define CONSTEXPR_INFINITY const
#else
#  define CONSTEXPR_INFINITY constexpr
#endif

#if PRINCIPIA_COMPILER_MSVC
#define MSVC_ONLY_TEST(test_name) test_name
#else
#define MSVC_ONLY_TEST(test_name) DISABLED_##test_name
#endif

// For templates in macro parameters.
#define TEMPLATE(...) template<__VA_ARGS__>

// Forward declaration of a class or struct declared in an internal namespace
// according to #602.
// Usage:
// FORWARD_DECLARE_FROM(p1, struct, T);
// FORWARD_DECLARE_FROM(p2, TEMPLATE(int i) class, U);
#define FORWARD_DECLARE_FROM(package_name,           \
                             template_and_class_key, \
                             declared_name)          \
namespace internal_##package_name {                  \
template_and_class_key declared_name;                \
}                                                    \
using internal_##package_name::declared_name

}  // namespace base
}  // namespace principia
<commit_msg>Obsolete macro.<commit_after>
#pragma once

#include <cstdlib>
#include <string>

namespace principia {
namespace base {

#define STRINGIFY(X) #X
#define STRINGIFY_EXPANSION(X) STRINGIFY(X)

// See http://goo.gl/2EVxN4 for a partial overview of compiler detection and
// version macros.  We cannot use |COMPILER_MSVC| because it conflicts with
// a macro in the benchmark library, so the macros have obnoxiously long names.
// TODO(phl): See whether that |COMPILER_MSVC| macro can be removed from port.h.
#if defined(_MSC_VER) && defined(__clang__)
#define PRINCIPIA_COMPILER_CLANG_CL 1
char const* const CompilerName = "Clang-cl";
char const* const CompilerVersion = __VERSION__;
#elif defined(__clang__)
#define PRINCIPIA_COMPILER_CLANG 1
char const* const CompilerName = "Clang";
char const* const CompilerVersion = __VERSION__;
#elif defined(_MSC_VER)
#define PRINCIPIA_COMPILER_MSVC 1
char const* const CompilerName = "Microsoft Visual C++";
char const* const CompilerVersion = STRINGIFY_EXPANSION(_MSC_FULL_VER);
#elif defined(__ICC) || defined(__INTEL_COMPILER)
#define PRINCIPIA_COMPILER_ICC 1
char const* const CompilerName = "Intel C++ Compiler";
char const* const CompilerVersion = __VERSION__;
#elif defined(__GNUC__)
#define PRINCIPIA_COMPILER_GCC 1
char const* const CompilerName = "G++";
char const* const CompilerVersion = __VERSION__;
#else
#error "What is this, Borland C++?"
#endif

#if defined(__APPLE__)
#define OS_MACOSX 1
char const* const OperatingSystem = "OS X";
#elif defined(__linux__)
#define OS_LINUX 1
char const* const OperatingSystem = "Linux";
#elif defined(__FreeBSD__)
#define OS_FREEBSD 1
char const* const OperatingSystem = "FreeBSD";
#elif defined(_WIN32)
#define OS_WIN 1
char const* const OperatingSystem = "Windows";
#else
#error "Try OS/360."
#endif

#if defined(__i386) || defined(_M_IX86)
#define ARCH_CPU_X86_FAMILY 1
#define ARCH_CPU_X86 1
#define ARCH_CPU_32_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 1
char const* const Architecture = "x86";
#elif defined(_M_X64) || defined(__x86_64__)
#define ARCH_CPU_X86_FAMILY 1
#define ARCH_CPU_X86_64 1
#define ARCH_CPU_64_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 1
char const* const Architecture = "x86-64";
#else
#error "Have you tried a Cray-1?"
#endif

#if defined(CDECL)
#  error "CDECL already defined"
#else
// Architecture macros from http://goo.gl/ZypnO8.
// We use cdecl on x86, the calling convention is unambiguous on x86-64.
#  if ARCH_CPU_X86
#    if PRINCIPIA_COMPILER_CLANG ||  \
        PRINCIPIA_COMPILER_MSVC ||   \
        PRINCIPIA_COMPILER_CLANG_CL
#      define CDECL __cdecl
#    elif PRINCIPIA_COMPILER_ICC || PRINCIPIA_COMPILER_GCC
#      define CDECL __attribute__((cdecl))
#    else
#      error "Get a real compiler!"
#    endif
#  elif ARCH_CPU_X86_64
#    define CDECL
#  else
#    error "Have you tried a Cray-1?"
#  endif
#endif

// DLL-exported functions for interfacing with Platform Invocation Services.
#if defined(PRINCIPIA_DLL)
#  error "PRINCIPIA_DLL already defined"
#else
#  if OS_WIN
#    if PRINCIPIA_DLL_IMPORT
#      define PRINCIPIA_DLL __declspec(dllimport)
#    else
#      define PRINCIPIA_DLL __declspec(dllexport)
#    endif
#  else
#    define PRINCIPIA_DLL __attribute__((visibility("default")))
#  endif
#endif

// DLL-exported functions for isolated physics optimization.
#if defined(PHYSICS_DLL)
#  error "PHYSICS_DLL already defined"
#else
#  if OS_WIN
#    if PHYSICS_DLL_IMPORT
#      define PHYSICS_DLL __declspec(dllimport)
#      define PHYSICS_DLL_TEMPLATE_CLASS extern template class PHYSICS_DLL
#    else
#      define PHYSICS_DLL __declspec(dllexport)
#      define PHYSICS_DLL_TEMPLATE_CLASS template class PHYSICS_DLL
#    endif
#  else
#    define PHYSICS_DLL __attribute__((visibility("default")))
     // No isolated physics library on Linux or Macintosh at the moment.
#    define PHYSICS_DLL_TEMPLATE_CLASS template class PHYSICS_DLL
#  endif
#endif

// A function for use on control paths that don't return a value, typically
// because they end with a |LOG(FATAL)|.
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
[[noreturn]]
#elif PRINCIPIA_COMPILER_MSVC
__declspec(noreturn)
#elif PRINCIPIA_COMPILER_ICC
__attribute__((noreturn))
#else
#error "What compiler is this?"
#endif
inline void noreturn() { std::exit(0); }

// Used to force inlining.
#if PRINCIPIA_COMPILER_CLANG    ||  \
    PRINCIPIA_COMPILER_CLANG_CL ||  \
    PRINCIPIA_COMPILER_GCC
#  define FORCE_INLINE(specifiers) [[gnu::always_inline]] specifiers // NOLINT
#elif PRINCIPIA_COMPILER_MSVC
#  define FORCE_INLINE(specifiers) specifiers __forceinline
#elif PRINCIPIA_COMPILER_ICC
#  define FORCE_INLINE(specifiers) __attribute__((always_inline))
#else
#  error "What compiler is this?"
#endif

// Used to emit the function signature.
#if PRINCIPIA_COMPILER_CLANG    ||  \
    PRINCIPIA_COMPILER_CLANG_CL ||  \
    PRINCIPIA_COMPILER_GCC
#  define FUNCTION_SIGNATURE __PRETTY_FUNCTION__
#elif PRINCIPIA_COMPILER_MSVC
#  define FUNCTION_SIGNATURE __FUNCSIG__
#else
#  error "What compiler is this?"
#endif

// We assume that the processor is at least a Prescott since we only support
// 64-bit architectures.
#define PRINCIPIA_USE_SSE3_INTRINSICS !_DEBUG

// Thread-safety analysis.
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
#  define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#  define EXCLUDES(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#  define GUARDED_BY(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(__VA_ARGS__))
#  define REQUIRES(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#  define REQUIRES_SHARED(...) \
       THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#else
#  define EXCLUDES(x)
#  define GUARDED_BY(x)
#  define REQUIRES(x)
#  define REQUIRES_SHARED(x)
#endif

// Unicode.
#if OS_WIN
#  define UNICODE_PATH(x) u ## x
#else
#  define UNICODE_PATH(x) u8 ## x
#endif

// Mutex.
#if !OS_MACOSX
#  define HAS_SHARED_MUTEX 1
#endif

#define NAMED(expression) #expression << ": " << (expression)

// Needed to circumvent lint warnings in constexpr functions where CHECK_LT and
// friends cannot be used.
#define CONSTEXPR_CHECK(condition) CHECK(condition)

// Clang for some reason doesn't like FP arithmetic that yields infinities in
// constexpr code (MSVC and GCC are fine with that).
#if PRINCIPIA_COMPILER_CLANG || PRINCIPIA_COMPILER_CLANG_CL
#  define CONSTEXPR_INFINITY const
#else
#  define CONSTEXPR_INFINITY constexpr
#endif

#if PRINCIPIA_COMPILER_MSVC
#define MSVC_ONLY_TEST(test_name) test_name
#else
#define MSVC_ONLY_TEST(test_name) DISABLED_##test_name
#endif

// For templates in macro parameters.
#define TEMPLATE(...) template<__VA_ARGS__>

// Forward declaration of a class or struct declared in an internal namespace
// according to #602.
// Usage:
// FORWARD_DECLARE_FROM(p1, struct, T);
// FORWARD_DECLARE_FROM(p2, TEMPLATE(int i) class, U);
#define FORWARD_DECLARE_FROM(package_name,           \
                             template_and_class_key, \
                             declared_name)          \
namespace internal_##package_name {                  \
template_and_class_key declared_name;                \
}                                                    \
using internal_##package_name::declared_name

}  // namespace base
}  // namespace principia
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: PaneDockingWindow.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-18 16:47:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "PaneDockingWindow.hxx"
#include "ViewShellBase.hxx"
#include "Window.hxx"
#include "sdresid.hxx"
#include "res_bmp.hrc"
#ifndef _SFXDISPATCH_HXX
#include <sfx2/dispatch.hxx>
#endif
#include <vcl/toolbox.hxx>
#ifndef _SV_TASKPANELIST_HXX
#include <vcl/taskpanelist.hxx>
#endif

namespace sd {

PaneDockingWindow::PaneDockingWindow (
    SfxBindings *pBindings,
    SfxChildWindow *pChildWindow,
    ::Window* pParent,
    const ResId& rResId,
    PaneManager::PaneType ePane)
    : SfxDockingWindow (
        pBindings,
        pChildWindow,
        pParent,
        rResId
        ),
      mePane(ePane),
      msTitle(),
      mpTitleToolBox(NULL),
      maBorder (3,1,3,3),
      mnChildWindowId(pChildWindow->GetType())
{
    SetBackground (Wallpaper());

    InitializeTitleToolBox();

    ViewShellBase* pBase = ViewShellBase::GetViewShellBase(
        pBindings->GetDispatcher()->GetFrame());
    if (pBase != NULL)
    {
        msTitle = pBase->GetPaneManager().GetWindowTitle (mePane);
        pBase->GetPaneManager().SetWindow (mePane, this);
    }

    // Tell the system window about the new docking window so that it can be
    // reached via the keyboard.
    SystemWindow* pSystemWindow = GetSystemWindow();
    if (pSystemWindow != NULL)
        pSystemWindow->GetTaskPaneList()->AddWindow(this);
}

PaneDockingWindow::~PaneDockingWindow (void)
{
    ViewShellBase* pBase = ViewShellBase::GetViewShellBase(
        GetBindings().GetDispatcher()->GetFrame());

    // Tell the next system window that the docking window is no longer
    // available.
    SystemWindow* pSystemWindow = GetSystemWindow();
    if (pSystemWindow != NULL)
        pSystemWindow->GetTaskPaneList()->RemoveWindow(this);

    // Tell the ViewShellBase that the window of this slide sorter is not
    // available anymore.
    if (pBase != NULL)
        pBase->GetPaneManager().SetWindow (mePane, NULL);
}

void PaneDockingWindow::SetTitle (const String& rsTitle)
{
    msTitle = rsTitle;
    Invalidate();
}

void PaneDockingWindow::Resize (void)
{
    SfxDockingWindow::Resize();
    Size aWindowSize (GetOutputSizePixel());
    Size aToolBoxSize (0,0);
    int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight());

    // Place the title tool box.
    if (mpTitleToolBox.get() != NULL)
    {
        if (IsFloatingMode())
            mpTitleToolBox->HideItem (1);
        else
            mpTitleToolBox->ShowItem (1);

        aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel();
        if (aToolBoxSize.Height() > nTitleBarHeight)
            nTitleBarHeight = aToolBoxSize.Height();
        mpTitleToolBox->SetPosSizePixel (
            Point(aWindowSize.Width()-aToolBoxSize.Width(),
                (nTitleBarHeight-aToolBoxSize.Height())/2),
            aToolBoxSize);
    }

    // Place the view shell.
    ViewShellBase* pBase (ViewShellBase::GetViewShellBase(
        GetBindings().GetDispatcher()->GetFrame()));
    if (pBase != NULL)
    {
        ViewShell* pViewShell = pBase->GetPaneManager().GetViewShell (mePane);
        if (pViewShell != NULL)
        {
            ::sd::Window* pWindow = pViewShell->GetActiveWindow();
            if (nTitleBarHeight < aToolBoxSize.Height())
                nTitleBarHeight = aToolBoxSize.Height();
            aWindowSize.Height() -= nTitleBarHeight;
            pViewShell->Resize(
                Point(maBorder.Left(),nTitleBarHeight+maBorder.Top()),
                Size (aWindowSize.Width()-maBorder.Left()-maBorder.Right(),
                    aWindowSize.Height()-maBorder.Top()-maBorder.Bottom()));
        }
    }
}

void PaneDockingWindow::Paint (const Rectangle& rRectangle)
{
    SfxDockingWindow::Paint (rRectangle);
    int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight());
    Size aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel();
    if (aToolBoxSize.Height() > nTitleBarHeight)
        nTitleBarHeight = aToolBoxSize.Height();
    Color aOriginalLineColor (GetLineColor());
    Color aOriginalFillColor (GetFillColor());
    SetFillColor (GetSettings().GetStyleSettings().GetDialogColor());
    SetLineColor ();

    // Make font bold.
    const Font& rOriginalFont (GetFont());
    Font aFont (rOriginalFont);
    aFont.SetWeight (WEIGHT_BOLD);
    SetFont (aFont);

    // Set border values.
    Size aWindowSize (GetOutputSizePixel());
    int nOuterLeft = 0;
    int nInnerLeft = nOuterLeft + maBorder.Left() - 1;
    int nOuterRight = aWindowSize.Width() - 1;
    int nInnerRight = nOuterRight - maBorder.Right() + 1;
    int nInnerTop = nTitleBarHeight + maBorder.Top() - 1;
    int nOuterBottom = aWindowSize.Height() - 1;
    int nInnerBottom = nOuterBottom - maBorder.Bottom() + 1;

    // Paint title bar background.
    Rectangle aTitleBarBox (Rectangle(
        nOuterLeft,
        0,
        nOuterRight,
        nInnerTop-1));
    DrawRect (aTitleBarBox);

    if (nInnerLeft > nOuterLeft)
        DrawRect (
            Rectangle (nOuterLeft, nInnerTop, nInnerLeft, nInnerBottom));
    if (nOuterRight > nInnerRight)
        DrawRect (
            Rectangle (nInnerRight, nInnerTop, nOuterRight, nInnerBottom));
    if (nInnerBottom < nOuterBottom)
        DrawRect (
            Rectangle (nOuterLeft, nInnerBottom, nOuterRight, nOuterBottom));

    // Paint bevel border.
    SetFillColor ();
    SetLineColor (GetSettings().GetStyleSettings().GetShadowColor());
    if (maBorder.Top() > 0)
        DrawLine (
            Point(nInnerLeft,nInnerTop),
            Point(nInnerLeft,nInnerBottom));
    if (maBorder.Left() > 0)
        DrawLine (
            Point(nInnerLeft,nInnerTop),
            Point(nInnerRight,nInnerTop));
    SetLineColor (GetSettings().GetStyleSettings().GetLightColor());
    if (maBorder.Bottom() > 0)
        DrawLine (
            Point(nInnerRight,nInnerBottom),
            Point(nInnerLeft,nInnerBottom));
    if (maBorder.Right() > 0)
        DrawLine (
            Point(nInnerRight,nInnerBottom),
            Point(nInnerRight,nInnerTop));

    // Paint title bar text.
    SetLineColor (GetSettings().GetStyleSettings().GetActiveTextColor());
    SetFillColor ();
    aTitleBarBox.Left() += 3;
    DrawText (aTitleBarBox, msTitle,
        TEXT_DRAW_LEFT
        | TEXT_DRAW_VCENTER
        | TEXT_DRAW_MULTILINE
        | TEXT_DRAW_WORDBREAK);

    // Restore original values of the output device.
    SetFont (rOriginalFont);
    SetFillColor (aOriginalFillColor);
}

void PaneDockingWindow::InitializeTitleToolBox (void)
{
    if (mpTitleToolBox.get() == NULL)
    {
        // Initialize the title tool box.
        mpTitleToolBox.reset (new ToolBox(this));
        mpTitleToolBox->SetSelectHdl (
            LINK(this, PaneDockingWindow, ToolboxSelectHandler));
        mpTitleToolBox->SetOutStyle (TOOLBOX_STYLE_FLAT);
        mpTitleToolBox->SetBackground (Wallpaper (
            GetSettings().GetStyleSettings().GetDialogColor()));
        mpTitleToolBox->Show();
    }
    else
        mpTitleToolBox->Clear();

    // Get the closer bitmap and set it as right most button.
    Bitmap aBitmap (SdResId (BMP_CLOSE_DOC));
    Bitmap aBitmapHC (SdResId (BMP_CLOSE_DOC_H));
    Image aImage = Image (aBitmap, Color (COL_LIGHTMAGENTA));
    Image aImageHC = Image (aBitmapHC, Color (BMP_COLOR_HIGHCONTRAST));
    mpTitleToolBox->InsertItem (1,
        GetSettings().GetStyleSettings().GetMenuBarColor().IsDark()
        ? aImageHC
        : aImage);
    mpTitleToolBox->ShowItem (1);
}

USHORT PaneDockingWindow::AddMenu (
    const String& rsMenuName,
    ULONG nHelpId,
    const Link& rCallback)
{
    // Add the menu before the closer button.
    int nItemCount (mpTitleToolBox->GetItemCount());
    USHORT nItemId = nItemCount+1;
    mpTitleToolBox->InsertItem (
        nItemId,
        rsMenuName,
        TIB_DROPDOWNONLY,
        nItemCount-1);
    mpTitleToolBox->SetHelpId( nItemId, nHelpId );
    mpTitleToolBox->SetClickHdl (rCallback);
    mpTitleToolBox->SetDropdownClickHdl (rCallback);

    return nItemCount+1;
}

IMPL_LINK(PaneDockingWindow, ToolboxSelectHandler, ToolBox*, pToolBox)
{
    USHORT nId = pToolBox->GetCurItemId();

    if (nId == 1)
    {
        EndTracking();
        SfxBoolItem aVisibility (mnChildWindowId, FALSE);
        GetBindings().GetDispatcher()->Execute (
            mnChildWindowId,
            SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
            &aVisibility,
            NULL);
    }

    return 0;
}

long PaneDockingWindow::Notify( NotifyEvent& rNEvt )
{
    return SfxDockingWindow::Notify (rNEvt);
}

void PaneDockingWindow::StateChanged( StateChangedType nType )
{
    switch (nType)
    {
        case STATE_CHANGE_INITSHOW:
            Resize();
            break;
    }
    SfxDockingWindow::StateChanged (nType);
}

void PaneDockingWindow::DataChanged (const DataChangedEvent& rEvent)
{
    SfxDockingWindow::DataChanged (rEvent);

    switch (rEvent.GetType())
    {
        case DATACHANGED_SETTINGS:
            if ((rEvent.GetFlags() & SETTINGS_STYLE) == NULL)
                break;
            // else fall through.
        case DATACHANGED_FONTS:
        case DATACHANGED_FONTSUBSTITUTION:
        {
            const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

            // Font.
            Font aFont = rStyleSettings.GetAppFont();
            if (IsControlFont())
                aFont.Merge(GetControlFont());
            SetZoomedPointFont(aFont);

            // Color.
            Color aColor;
            if (IsControlForeground())
                aColor = GetControlForeground();
            else
                aColor = rStyleSettings.GetButtonTextColor();
            SetTextColor(aColor);
            SetTextFillColor();

            Resize();
            Invalidate();
        }
        break;
    }
}

} // end of namespace ::sd
<commit_msg>INTEGRATION: CWS impress52 (1.9.44); FILE MERGED 2005/04/27 14:09:57 af 1.9.44.1: #i48263# Added WindowEventListener() link method.<commit_after>/*************************************************************************
 *
 *  $RCSfile: PaneDockingWindow.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2005-05-02 13:17:56 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "PaneDockingWindow.hxx"
#include "ViewShellBase.hxx"
#include "Window.hxx"
#include "sdresid.hxx"
#include "res_bmp.hrc"
#ifndef _SFXDISPATCH_HXX
#include <sfx2/dispatch.hxx>
#endif
#include <vcl/toolbox.hxx>
#ifndef _SV_TASKPANELIST_HXX
#include <vcl/taskpanelist.hxx>
#endif

namespace sd {

PaneDockingWindow::PaneDockingWindow (
    SfxBindings *pBindings,
    SfxChildWindow *pChildWindow,
    ::Window* pParent,
    const ResId& rResId,
    PaneManager::PaneType ePane)
    : SfxDockingWindow (
        pBindings,
        pChildWindow,
        pParent,
        rResId
        ),
      mePane(ePane),
      msTitle(),
      mpTitleToolBox(NULL),
      maBorder (3,1,3,3),
      mnChildWindowId(pChildWindow->GetType())
{
    SetBackground (Wallpaper());

    InitializeTitleToolBox();

    ViewShellBase* pBase = ViewShellBase::GetViewShellBase(
        pBindings->GetDispatcher()->GetFrame());
    if (pBase != NULL)
    {
        msTitle = pBase->GetPaneManager().GetWindowTitle (mePane);
        pBase->GetPaneManager().SetWindow (mePane, this);
    }

    // Tell the system window about the new docking window so that it can be
    // reached via the keyboard.
    SystemWindow* pSystemWindow = GetSystemWindow();
    if (pSystemWindow != NULL)
        pSystemWindow->GetTaskPaneList()->AddWindow(this);

    AddEventListener(LINK(this,PaneDockingWindow,WindowEventListener));
}

PaneDockingWindow::~PaneDockingWindow (void)
{
    RemoveEventListener(LINK(this,PaneDockingWindow,WindowEventListener));

    ViewShellBase* pBase = ViewShellBase::GetViewShellBase(
        GetBindings().GetDispatcher()->GetFrame());

    // Tell the next system window that the docking window is no longer
    // available.
    SystemWindow* pSystemWindow = GetSystemWindow();
    if (pSystemWindow != NULL)
        pSystemWindow->GetTaskPaneList()->RemoveWindow(this);

    // Tell the ViewShellBase that the window of this slide sorter is not
    // available anymore.
    if (pBase != NULL)
        pBase->GetPaneManager().SetWindow (mePane, NULL);
}

void PaneDockingWindow::SetTitle (const String& rsTitle)
{
    msTitle = rsTitle;
    Invalidate();
}

void PaneDockingWindow::Resize (void)
{
    SfxDockingWindow::Resize();
    Size aWindowSize (GetOutputSizePixel());
    Size aToolBoxSize (0,0);
    int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight());

    // Place the title tool box.
    if (mpTitleToolBox.get() != NULL)
    {
        if (IsFloatingMode())
            mpTitleToolBox->HideItem (1);
        else
            mpTitleToolBox->ShowItem (1);

        aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel();
        if (aToolBoxSize.Height() > nTitleBarHeight)
            nTitleBarHeight = aToolBoxSize.Height();
        mpTitleToolBox->SetPosSizePixel (
            Point(aWindowSize.Width()-aToolBoxSize.Width(),
                (nTitleBarHeight-aToolBoxSize.Height())/2),
            aToolBoxSize);
    }

    // Place the view shell.
    ViewShellBase* pBase (ViewShellBase::GetViewShellBase(
        GetBindings().GetDispatcher()->GetFrame()));
    if (pBase != NULL)
    {
        ViewShell* pViewShell = pBase->GetPaneManager().GetViewShell (mePane);
        if (pViewShell != NULL)
        {
            ::sd::Window* pWindow = pViewShell->GetActiveWindow();
            if (nTitleBarHeight < aToolBoxSize.Height())
                nTitleBarHeight = aToolBoxSize.Height();
            aWindowSize.Height() -= nTitleBarHeight;
            pViewShell->Resize(
                Point(maBorder.Left(),nTitleBarHeight+maBorder.Top()),
                Size (aWindowSize.Width()-maBorder.Left()-maBorder.Right(),
                    aWindowSize.Height()-maBorder.Top()-maBorder.Bottom()));
        }
    }
}

void PaneDockingWindow::Paint (const Rectangle& rRectangle)
{
    SfxDockingWindow::Paint (rRectangle);
    int nTitleBarHeight (GetSettings().GetStyleSettings().GetTitleHeight());
    Size aToolBoxSize = mpTitleToolBox->CalcWindowSizePixel();
    if (aToolBoxSize.Height() > nTitleBarHeight)
        nTitleBarHeight = aToolBoxSize.Height();
    Color aOriginalLineColor (GetLineColor());
    Color aOriginalFillColor (GetFillColor());
    SetFillColor (GetSettings().GetStyleSettings().GetDialogColor());
    SetLineColor ();

    // Make font bold.
    const Font& rOriginalFont (GetFont());
    Font aFont (rOriginalFont);
    aFont.SetWeight (WEIGHT_BOLD);
    SetFont (aFont);

    // Set border values.
    Size aWindowSize (GetOutputSizePixel());
    int nOuterLeft = 0;
    int nInnerLeft = nOuterLeft + maBorder.Left() - 1;
    int nOuterRight = aWindowSize.Width() - 1;
    int nInnerRight = nOuterRight - maBorder.Right() + 1;
    int nInnerTop = nTitleBarHeight + maBorder.Top() - 1;
    int nOuterBottom = aWindowSize.Height() - 1;
    int nInnerBottom = nOuterBottom - maBorder.Bottom() + 1;

    // Paint title bar background.
    Rectangle aTitleBarBox (Rectangle(
        nOuterLeft,
        0,
        nOuterRight,
        nInnerTop-1));
    DrawRect (aTitleBarBox);

    if (nInnerLeft > nOuterLeft)
        DrawRect (
            Rectangle (nOuterLeft, nInnerTop, nInnerLeft, nInnerBottom));
    if (nOuterRight > nInnerRight)
        DrawRect (
            Rectangle (nInnerRight, nInnerTop, nOuterRight, nInnerBottom));
    if (nInnerBottom < nOuterBottom)
        DrawRect (
            Rectangle (nOuterLeft, nInnerBottom, nOuterRight, nOuterBottom));

    // Paint bevel border.
    SetFillColor ();
    SetLineColor (GetSettings().GetStyleSettings().GetShadowColor());
    if (maBorder.Top() > 0)
        DrawLine (
            Point(nInnerLeft,nInnerTop),
            Point(nInnerLeft,nInnerBottom));
    if (maBorder.Left() > 0)
        DrawLine (
            Point(nInnerLeft,nInnerTop),
            Point(nInnerRight,nInnerTop));
    SetLineColor (GetSettings().GetStyleSettings().GetLightColor());
    if (maBorder.Bottom() > 0)
        DrawLine (
            Point(nInnerRight,nInnerBottom),
            Point(nInnerLeft,nInnerBottom));
    if (maBorder.Right() > 0)
        DrawLine (
            Point(nInnerRight,nInnerBottom),
            Point(nInnerRight,nInnerTop));

    // Paint title bar text.
    SetLineColor (GetSettings().GetStyleSettings().GetActiveTextColor());
    SetFillColor ();
    aTitleBarBox.Left() += 3;
    DrawText (aTitleBarBox, msTitle,
        TEXT_DRAW_LEFT
        | TEXT_DRAW_VCENTER
        | TEXT_DRAW_MULTILINE
        | TEXT_DRAW_WORDBREAK);

    // Restore original values of the output device.
    SetFont (rOriginalFont);
    SetFillColor (aOriginalFillColor);
}

void PaneDockingWindow::InitializeTitleToolBox (void)
{
    if (mpTitleToolBox.get() == NULL)
    {
        // Initialize the title tool box.
        mpTitleToolBox.reset (new ToolBox(this));
        mpTitleToolBox->SetSelectHdl (
            LINK(this, PaneDockingWindow, ToolboxSelectHandler));
        mpTitleToolBox->SetOutStyle (TOOLBOX_STYLE_FLAT);
        mpTitleToolBox->SetBackground (Wallpaper (
            GetSettings().GetStyleSettings().GetDialogColor()));
        mpTitleToolBox->Show();
    }
    else
        mpTitleToolBox->Clear();

    // Get the closer bitmap and set it as right most button.
    Bitmap aBitmap (SdResId (BMP_CLOSE_DOC));
    Bitmap aBitmapHC (SdResId (BMP_CLOSE_DOC_H));
    Image aImage = Image (aBitmap, Color (COL_LIGHTMAGENTA));
    Image aImageHC = Image (aBitmapHC, Color (BMP_COLOR_HIGHCONTRAST));
    mpTitleToolBox->InsertItem (1,
        GetSettings().GetStyleSettings().GetMenuBarColor().IsDark()
        ? aImageHC
        : aImage);
    mpTitleToolBox->ShowItem (1);
}

USHORT PaneDockingWindow::AddMenu (
    const String& rsMenuName,
    ULONG nHelpId,
    const Link& rCallback)
{
    // Add the menu before the closer button.
    int nItemCount (mpTitleToolBox->GetItemCount());
    USHORT nItemId = nItemCount+1;
    mpTitleToolBox->InsertItem (
        nItemId,
        rsMenuName,
        TIB_DROPDOWNONLY,
        nItemCount-1);
    mpTitleToolBox->SetHelpId( nItemId, nHelpId );
    mpTitleToolBox->SetClickHdl (rCallback);
    mpTitleToolBox->SetDropdownClickHdl (rCallback);

    return nItemCount+1;
}

IMPL_LINK(PaneDockingWindow, ToolboxSelectHandler, ToolBox*, pToolBox)
{
    USHORT nId = pToolBox->GetCurItemId();

    if (nId == 1)
    {
        EndTracking();
        SfxBoolItem aVisibility (mnChildWindowId, FALSE);
        GetBindings().GetDispatcher()->Execute (
            mnChildWindowId,
            SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
            &aVisibility,
            NULL);
    }

    return 0;
}

long PaneDockingWindow::Notify( NotifyEvent& rNEvt )
{
    return SfxDockingWindow::Notify (rNEvt);
}

void PaneDockingWindow::StateChanged( StateChangedType nType )
{
    switch (nType)
    {
        case STATE_CHANGE_INITSHOW:
            Resize();
            break;
    }
    SfxDockingWindow::StateChanged (nType);
}

void PaneDockingWindow::DataChanged (const DataChangedEvent& rEvent)
{
    SfxDockingWindow::DataChanged (rEvent);

    switch (rEvent.GetType())
    {
        case DATACHANGED_SETTINGS:
            if ((rEvent.GetFlags() & SETTINGS_STYLE) == NULL)
                break;
            // else fall through.
        case DATACHANGED_FONTS:
        case DATACHANGED_FONTSUBSTITUTION:
        {
            const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

            // Font.
            Font aFont = rStyleSettings.GetAppFont();
            if (IsControlFont())
                aFont.Merge(GetControlFont());
            SetZoomedPointFont(aFont);

            // Color.
            Color aColor;
            if (IsControlForeground())
                aColor = GetControlForeground();
            else
                aColor = rStyleSettings.GetButtonTextColor();
            SetTextColor(aColor);
            SetTextFillColor();

            Resize();
            Invalidate();
        }
        break;
    }
}

IMPL_LINK(PaneDockingWindow, WindowEventListener, VclSimpleEvent*, pEvent)
{
    if (pEvent!=NULL && pEvent->ISA(VclWindowEvent))
    {
        ViewShellBase* pBase = ViewShellBase::GetViewShellBase(
            GetBindings().GetDispatcher()->GetFrame());

        VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
        switch (pWindowEvent->GetId())
        {
            case VCLEVENT_WINDOW_SHOW:
                if (pBase != NULL)
                    pBase->GetPaneManager().RequestWindowVisibilityChange(
                        mePane,
                        true,
                        PaneManager::CM_ASYNCHRONOUS);
                break;

            case VCLEVENT_WINDOW_HIDE:
                if (pBase != NULL)
                    pBase->GetPaneManager().RequestWindowVisibilityChange(
                        mePane,
                        false,
                        PaneManager::CM_ASYNCHRONOUS);
                break;
        }
    }
    return 1;
}

} // end of namespace ::sd
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_TOPOLOGY_PLC_HPP
#define VIENNAGRID_TOPOLOGY_PLC_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"
#include "viennagrid/topology/simplex.hpp"
#include "viennagrid/topology/polygon.hpp"
#include "viennagrid/element/element_view.hpp"

/** @file polygon.hpp
    @brief Provides the topological definition of a polygon
*/

namespace viennagrid
{

  struct plc_tag
  {
    typedef polygon_tag facet_tag;

    enum{ dim = 2 };
    static std::string name() { return "PLC"; }
  };

  namespace topology
  {

    //Line:
    /** @brief Topological description of the 0-cells of a polygon */
    template <>
    struct boundary_cells<plc_tag, vertex_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template <>
    struct boundary_cells<plc_tag, line_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template <>
    struct boundary_cells<plc_tag, polygon_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, polygon_tag, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & element, inserter_type & inserter)
        {}
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, line_tag, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & plc, inserter_type & inserter)
        {
            typedef typename result_of::element<element_type, polygon_tag>::type PolygonType;
            typedef typename result_of::element_range<element_type, polygon_tag>::type PolygonRange;
            typedef typename result_of::iterator<PolygonRange>::type PolygonIterator;

            PolygonRange polygons = elements<polygon_tag>(plc);
            for (PolygonIterator pit = polygons.begin(); pit != polygons.end(); ++pit)
            {
                typedef typename result_of::element_range<PolygonType, line_tag>::type LineOnPolygonRange;
                typedef typename result_of::hook_iterator<LineOnPolygonRange>::type LineOnPolygonIterator;

                LineOnPolygonRange lines = elements<line_tag>(*pit);
                for (LineOnPolygonIterator lphit = lines.begin(); lphit != lines.end(); ++lphit)
                {
                    plc.container( line_tag() ).insert_hook( *lphit );
                    if (is_tagged<bounding_tag>(*pit, plc))
                        tag<bounding_tag>(viennagrid::dereference_hook(plc,*lphit), plc);
                }
            }
        }
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, simplex_tag<0>, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & plc, inserter_type & inserter)
        {
            typedef typename result_of::element<element_type, line_tag>::type LineType;
            typedef typename result_of::element_range<element_type, line_tag>::type LineRange;
            typedef typename result_of::iterator<LineRange>::type LineIterator;

            LineRange lines = elements<line_tag>(plc);
            for (LineIterator lit = lines.hook_begin(); lit != lines.hook_end(); ++lit)
            {
                typedef typename result_of::element_range<LineType, vertex_tag>::type VertexOnLineRange;
                typedef typename result_of::hook_iterator<VertexOnLineRange>::type VertexOnLineHookIterator;

                VertexOnLineRange vertices = elements<vertex_tag>(*lit);
                for (VertexOnLineHookIterator vlhit = vertices.begin(); vlhit != vertices.end(); ++vlhit)
                    plc.container( vertex_tag() ).insert_hook( *vlhit );
            }

            typedef typename result_of::element<element_type, polygon_tag>::type PolygonType;
            typedef typename result_of::element_range<element_type, polygon_tag>::type PolygonRange;
            typedef typename result_of::iterator<PolygonRange>::type PolygonIterator;

            PolygonRange polygons = elements<polygon_tag>(plc);
            for (PolygonIterator pit = polygons.hook_begin(); pit != polygons.hook_end(); ++pit)
            {
                typedef typename result_of::element_range<PolygonType, vertex_tag>::type VertexOnPolygonRange;
                typedef typename result_of::hook_iterator<VertexOnPolygonRange>::type VertexOnPolygonIterator;

                VertexOnPolygonRange vertices = elements<vertex_tag>(*pit);
                for (VertexOnPolygonIterator vphit = vertices.begin(); vphit != vertices.end(); ++vphit)
                {
                    plc.container( vertex_tag() ).insert_hook( *vphit );
                    if (is_tagged<bounding_tag>(*pit, plc))
                        tag<bounding_tag>(viennagrid::dereference_hook(plc,*vphit), plc);
                }
            }
        }
    };

  } //topology
}

#endif

<commit_msg>adapted to new tagging system<commit_after>#ifndef VIENNAGRID_TOPOLOGY_PLC_HPP
#define VIENNAGRID_TOPOLOGY_PLC_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"
#include "viennagrid/topology/simplex.hpp"
#include "viennagrid/topology/polygon.hpp"
#include "viennagrid/element/tagging.hpp"

/** @file polygon.hpp
    @brief Provides the topological definition of a polygon
*/

namespace viennagrid
{

  struct plc_tag
  {
    typedef polygon_tag facet_tag;

    enum{ dim = 2 };
    static std::string name() { return "PLC"; }
  };

  namespace topology
  {

    //Line:
    /** @brief Topological description of the 0-cells of a polygon */
    template <>
    struct boundary_cells<plc_tag, vertex_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template <>
    struct boundary_cells<plc_tag, line_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template <>
    struct boundary_cells<plc_tag, polygon_tag>
    {
      typedef dynamic_unique_layout_tag     layout_tag;
      enum{ num = -1 };
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, polygon_tag, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & element, inserter_type & inserter)
        {}
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, line_tag, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & plc, inserter_type & inserter)
        {
            typedef typename result_of::element<element_type, polygon_tag>::type PolygonType;
            typedef typename result_of::element_range<element_type, polygon_tag>::type PolygonRange;
            typedef typename result_of::iterator<PolygonRange>::type PolygonIterator;

            PolygonRange polygons = elements<polygon_tag>(plc);
            for (PolygonIterator pit = polygons.begin(); pit != polygons.end(); ++pit)
            {
                typename tagging::result_of::element_tag<element_type, bounding_tag>::type plc_bounding_tag = tagging::create_element_tag<bounding_tag>(plc);

                typedef typename result_of::element_range<PolygonType, line_tag>::type LineOnPolygonRange;
                typedef typename result_of::hook_iterator<LineOnPolygonRange>::type LineOnPolygonIterator;

                LineOnPolygonRange lines = elements<line_tag>(*pit);
                for (LineOnPolygonIterator lphit = lines.begin(); lphit != lines.end(); ++lphit)
                {
                    plc.container( line_tag() ).insert_hook( *lphit );
                    if (tagging::is_tagged(*pit, plc_bounding_tag))
                        tagging::tag(viennagrid::dereference_hook(plc,*lphit), plc_bounding_tag);
                }
            }
        }
    };

    template<typename bnd_cell_type>
    struct bndcell_generator<plc_tag, simplex_tag<0>, bnd_cell_type>
    {
        template<typename element_type, typename inserter_type>
        static void create_bnd_cells(element_type & plc, inserter_type & inserter)
        {
            typedef typename result_of::element<element_type, line_tag>::type LineType;
            typedef typename result_of::element_range<element_type, line_tag>::type LineRange;
            typedef typename result_of::iterator<LineRange>::type LineIterator;

            LineRange lines = elements<line_tag>(plc);
            for (LineIterator lit = lines.hook_begin(); lit != lines.hook_end(); ++lit)
            {
                typedef typename result_of::element_range<LineType, vertex_tag>::type VertexOnLineRange;
                typedef typename result_of::hook_iterator<VertexOnLineRange>::type VertexOnLineHookIterator;

                VertexOnLineRange vertices = elements<vertex_tag>(*lit);
                for (VertexOnLineHookIterator vlhit = vertices.begin(); vlhit != vertices.end(); ++vlhit)
                    plc.container( vertex_tag() ).insert_hook( *vlhit );
            }

            typename tagging::result_of::element_tag<element_type, bounding_tag>::type plc_bounding_tag = tagging::create_element_tag<bounding_tag>(plc);

            typedef typename result_of::element<element_type, polygon_tag>::type PolygonType;
            typedef typename result_of::element_range<element_type, polygon_tag>::type PolygonRange;
            typedef typename result_of::iterator<PolygonRange>::type PolygonIterator;

            PolygonRange polygons = elements<polygon_tag>(plc);
            for (PolygonIterator pit = polygons.hook_begin(); pit != polygons.hook_end(); ++pit)
            {
                typedef typename result_of::element_range<PolygonType, vertex_tag>::type VertexOnPolygonRange;
                typedef typename result_of::hook_iterator<VertexOnPolygonRange>::type VertexOnPolygonIterator;

                VertexOnPolygonRange vertices = elements<vertex_tag>(*pit);
                for (VertexOnPolygonIterator vphit = vertices.begin(); vphit != vertices.end(); ++vphit)
                {
                    plc.container( vertex_tag() ).insert_hook( *vphit );
                    if (tagging::is_tagged(*pit, plc_bounding_tag))
                        tagging::tag(viennagrid::dereference_hook(plc,*vphit), plc_bounding_tag);
                }
            }
        }
    };

  } //topology
}

#endif

<|endoftext|>


<commit_before>#ifndef VIENNAGRID_TRAITS_POINT_HPP
#define VIENNAGRID_TRAITS_POINT_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"

/** @file viennagrid/traits/point.hpp
    @brief Provides a generic layer for point operations
*/

namespace viennagrid
{

  namespace traits
  {
    /** @brief  Returns the geometric dimension of a point */
    template <typename PointType>
    struct dimension;

    /** @brief  Returns the geometric dimension of a point. Specialization for a ViennaGrid point */
    template <typename CoordType, typename CoordinateSystem>
    struct dimension< point_t<CoordType, CoordinateSystem> >
    {
      enum { value = CoordinateSystem::dim };
    };

    /** @brief Returns the coordinate system of a point. Must be specialized for a user-provided point type */
    template <typename PointType>
    struct coordinate_system
    {
      //by default, we don't know anything about the point type, so let's complain at compile time
      typedef typename PointType::ERROR_UNKNOWN_COORDINATE_SYSTEM_FOR_POINT_TYPE    type;
    };

    /** @brief Returns the coordinate system of a point. Specialization for a ViennaGrid point. */
    template <typename CoordType, typename CoordinateSystem>
    struct coordinate_system< point_t<CoordType, CoordinateSystem> >
    {
      typedef CoordinateSystem    type;
    };

    /** @brief Returns the static (compile time) size of a point */
    template <typename PointType>
    struct static_size;

    /** @brief Returns the static (compile time) size of a point. Specialization for a ViennaGrid point. */
    template <typename CoordType, typename CoordinateSystem>
    struct static_size< point_t<CoordType, CoordinateSystem> >
    {
      enum { value = CoordinateSystem::dim };
    };

    /** @brief Returns the dynamic (run time) size of a point. Assumes a .size() member. Other cases must be provided with overloads */
    template <typename PointType>
    std::size_t dynamic_size(PointType const & p)
    {
      return p.size();
    }

    /** @brief  Value Type retrieval for a point. Returns the numeric type of each coordinate entry */
    template <typename PointType>
    struct value_type
    {
        typedef typename PointType::value_type type;
    };

    /** @brief  Value Type retrieval for a point. Returns the numeric type of each coordinate entry. Specialization for a ViennaGrid point. */
    template <typename CoordType, typename CoordinateSystem>
    struct value_type< point_t<CoordType, CoordinateSystem> >
    {
      typedef CoordType    type;
    };

  }
}

#endif
<commit_msg>removed value_type, use result_of::coord_type instead<commit_after>#ifndef VIENNAGRID_TRAITS_POINT_HPP
#define VIENNAGRID_TRAITS_POINT_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"

/** @file viennagrid/traits/point.hpp
    @brief Provides a generic layer for point operations
*/

namespace viennagrid
{

  namespace traits
  {
    /** @brief  Returns the geometric dimension of a point */
    template <typename PointType>
    struct dimension;

    /** @brief  Returns the geometric dimension of a point. Specialization for a ViennaGrid point */
    template <typename CoordType, typename CoordinateSystem>
    struct dimension< point_t<CoordType, CoordinateSystem> >
    {
      enum { value = CoordinateSystem::dim };
    };

    /** @brief Returns the coordinate system of a point. Must be specialized for a user-provided point type */
    template <typename PointType>
    struct coordinate_system
    {
      //by default, we don't know anything about the point type, so let's complain at compile time
      typedef typename PointType::ERROR_UNKNOWN_COORDINATE_SYSTEM_FOR_POINT_TYPE    type;
    };

    /** @brief Returns the coordinate system of a point. Specialization for a ViennaGrid point. */
    template <typename CoordType, typename CoordinateSystem>
    struct coordinate_system< point_t<CoordType, CoordinateSystem> >
    {
      typedef CoordinateSystem    type;
    };

    /** @brief Returns the static (compile time) size of a point */
    template <typename PointType>
    struct static_size;

    /** @brief Returns the static (compile time) size of a point. Specialization for a ViennaGrid point. */
    template <typename CoordType, typename CoordinateSystem>
    struct static_size< point_t<CoordType, CoordinateSystem> >
    {
      enum { value = CoordinateSystem::dim };
    };

    /** @brief Returns the dynamic (run time) size of a point. Assumes a .size() member. Other cases must be provided with overloads */
    template <typename PointType>
    std::size_t dynamic_size(PointType const & p)
    {
      return p.size();
    }

//     /** @brief  Value Type retrieval for a point. Returns the numeric type of each coordinate entry */
//     template <typename PointType>
//     struct value_type
//     {
//         typedef typename PointType::value_type type;
//     };
//
//     /** @brief  Value Type retrieval for a point. Returns the numeric type of each coordinate entry. Specialization for a ViennaGrid point. */
//     template <typename CoordType, typename CoordinateSystem>
//     struct value_type< point_t<CoordType, CoordinateSystem> >
//     {
//       typedef CoordType    type;
//     };

  }
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <iostream>

#include "utils/log_histogram.hh"

template<const log_histogram_options& opts>
struct node : public log_histogram_hook<opts> {
    size_t v;
    node(size_t v) : v(v) {}
};

template<const log_histogram_options& opts>
void test_with_options() {
    std::vector<std::unique_ptr<node<opts>>> nodes;

    log_histogram<node<opts>, opts> hist;

    BOOST_REQUIRE(hist.empty());

    unsigned i = 0;
    for (; i < opts.min_size; ++i) {
        nodes.push_back(std::make_unique<node<opts>>(i));
        hist.push(*nodes.back());
        BOOST_REQUIRE(!hist.contains_above_min());
        BOOST_REQUIRE(!hist.empty());
    }

    for (; i <= opts.max_size; ++i) {
        nodes.push_back(std::make_unique<node<opts>>(i));
        hist.push(*nodes.back());
        BOOST_REQUIRE(hist.contains_above_min());
        BOOST_REQUIRE(!hist.empty());
    }

    size_t count = 0;

    // Check monotonicity of buckets
    size_t prev_key = 0;
    for (auto&& bucket : hist.buckets()) {
        size_t max_key = 0;
        for (auto&& t : bucket) {
            ++count;
            auto key = t.v;
            if (prev_key) {
                assert(key > prev_key);
            }
            max_key = std::max(max_key, key);
        }
        if (max_key) {
            prev_key = max_key;
        }
    }

    BOOST_REQUIRE(count == (opts.max_size + 1));
}

constexpr log_histogram_options opts1{(1 << 4) + 3, 3, (1 << 6) + 2};
constexpr log_histogram_options opts2{(1 << 4) + 2, 1, (1 << 17) + 2};
constexpr log_histogram_options opts3{(1 << 4) + 1, 0, (1 << 17) + 2};
constexpr log_histogram_options opts4{(1 << 4) + 0, 3, (1 << 17)};

template<>
size_t hist_key<node<opts1>>(const node<opts1>& n) { return n.v; }

template<>
size_t hist_key<node<opts2>>(const node<opts2>& n) { return n.v; }

template<>
size_t hist_key<node<opts3>>(const node<opts3>& n) { return n.v; }

template<>
size_t hist_key<node<opts4>>(const node<opts4>& n) { return n.v; }

BOOST_AUTO_TEST_CASE(test_log_histogram) {
    test_with_options<opts1>();
    test_with_options<opts2>();
    test_with_options<opts3>();
    test_with_options<opts4>();
}
<commit_msg>tests: log_historgram_test: Fix compiation on Ubuntu<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <iostream>

#include "utils/log_histogram.hh"

template<const log_histogram_options& opts>
struct node : public log_histogram_hook<opts> {
    size_t v;
    node(size_t v) : v(v) {}
};

template<const log_histogram_options& opts>
void test_with_options() {
    std::vector<std::unique_ptr<node<opts>>> nodes;

    log_histogram<node<opts>, opts> hist;

    BOOST_REQUIRE(hist.empty());

    unsigned i = 0;
    for (; i < opts.min_size; ++i) {
        nodes.push_back(std::make_unique<node<opts>>(i));
        hist.push(*nodes.back());
        BOOST_REQUIRE(!hist.contains_above_min());
        BOOST_REQUIRE(!hist.empty());
    }

    for (; i <= opts.max_size; ++i) {
        nodes.push_back(std::make_unique<node<opts>>(i));
        hist.push(*nodes.back());
        BOOST_REQUIRE(hist.contains_above_min());
        BOOST_REQUIRE(!hist.empty());
    }

    size_t count = 0;

    // Check monotonicity of buckets
    size_t prev_key = 0;
    for (auto&& bucket : hist.buckets()) {
        size_t max_key = 0;
        for (auto&& t : bucket) {
            ++count;
            auto key = t.v;
            if (prev_key) {
                assert(key > prev_key);
            }
            max_key = std::max(max_key, key);
        }
        if (max_key) {
            prev_key = max_key;
        }
    }

    BOOST_REQUIRE(count == (opts.max_size + 1));
}

extern constexpr log_histogram_options opts1{(1 << 4) + 3, 3, (1 << 6) + 2};
extern constexpr log_histogram_options opts2{(1 << 4) + 2, 1, (1 << 17) + 2};
extern constexpr log_histogram_options opts3{(1 << 4) + 1, 0, (1 << 17) + 2};
extern constexpr log_histogram_options opts4{(1 << 4) + 0, 3, (1 << 17)};

template<>
size_t hist_key<node<opts1>>(const node<opts1>& n) { return n.v; }

template<>
size_t hist_key<node<opts2>>(const node<opts2>& n) { return n.v; }

template<>
size_t hist_key<node<opts3>>(const node<opts3>& n) { return n.v; }

template<>
size_t hist_key<node<opts4>>(const node<opts4>& n) { return n.v; }

BOOST_AUTO_TEST_CASE(test_log_histogram) {
    test_with_options<opts1>();
    test_with_options<opts2>();
    test_with_options<opts3>();
    test_with_options<opts4>();
}
<|endoftext|>