text:
#ifndef SHASTA_COMPRESSED_ASSEMBLY_GRAPH_HPP
#define SHASTA_COMPRESSED_ASSEMBLY_GRAPH_HPP

/*******************************************************************************

The compressed assembly graph is a representation of the assembly graph
in which each linear sequence of bubbles is compressed to a single edge.

*******************************************************************************/

#include "AssemblyGraph.hpp"

#include <boost/bimap.hpp>
#include <boost/graph/adjacency_list.hpp>

#include "array.hpp"
#include <map>

namespace shasta {
    class CompressedAssemblyGraph;
    class CompressedAssemblyGraphEdge;
    class CompressedAssemblyGraphVertex;

    using CompressedAssemblyGraphBaseClass =
        boost::adjacency_list<
        boost::listS,
        boost::listS,
        boost::bidirectionalS,
        CompressedAssemblyGraphVertex,
        CompressedAssemblyGraphEdge
        >;

    class Assembler;
}

class shasta::CompressedAssemblyGraphVertex {
public:
    AssemblyGraph::VertexId vertexId;

    CompressedAssemblyGraphVertex(AssemblyGraph::VertexId vertexId) :
        vertexId(vertexId) {}
};

class shasta::CompressedAssemblyGraphEdge {
public:

    // The chain of assembly graph vertices associated
    // with this edge.
    // This includes the assembly graph vertices
    // associated with the source and target of this edge.
    vector<AssemblyGraph::VertexId> vertices;

    // The chain of sets of parallel assembly graph edges.
    vector< vector<AssemblyGraph::EdgeId> > edges;

    // An id assigned to this edge of the compressed assembly graph
    // and used in gfa and other output.
    uint64_t id;
    string gfaId() const;

    // The minimum and maximum marker count (path length) in markers.
    uint64_t minMarkerCount;
    uint64_t maxMarkerCount;
    double averageMarkerCount() const
    {
        return double(minMarkerCount + maxMarkerCount) / 2.;
    }
    void fillMarkerCounts(const AssemblyGraph&);

    // Find the oriented reads that appear in marker graph vertices
    // internal to this edge of the compressed assembly graph.
    void findOrientedReads(const Assembler&);
    vector<OrientedReadId> orientedReadIds;
    vector<uint64_t> orientedReadIdsFrequency;

    // The edges that have at least one oriented read in common
    // with this edge.
    vector<CompressedAssemblyGraphBaseClass::edge_descriptor>
        relatedEdges;

    // Return the maximum number of branches in a bubble.
    uint64_t maxPloidy() const;

private:

    // Append to orientedReadIds the oriented reads that
    // appear in a given marker graph edge.
    void findOrientedReads(
        const Assembler&,
        const MarkerGraph::EdgeId&);

};

class shasta::CompressedAssemblyGraph :
    public CompressedAssemblyGraphBaseClass {
public:
    using VertexId = AssemblyGraph::VertexId;
    using EdgeId = AssemblyGraph::EdgeId;

    // Create the CompressedAssemblyGraph from the AssemblyGraph.
    CompressedAssemblyGraph(const Assembler&);

    // Create a local subgraph.
    // See createLocalSubgraph for argument explanation.
    CompressedAssemblyGraph(
        const CompressedAssemblyGraph& graph,
        const Assembler&,
        const vector<vertex_descriptor>& startVertices,
        uint64_t maxDistance,
        boost::bimap<vertex_descriptor, vertex_descriptor>& vertexMap,
        boost::bimap<edge_descriptor, edge_descriptor>& edgeMap,
        std::map<vertex_descriptor, uint64_t>& distanceMap
        );

    // Return the edge with a given GFA id.
    pair<edge_descriptor, bool> getEdgeFromGfaId(const string&) const;

    // GFA output (without sequence).
    void writeGfa(const string& fileName, double basesPerMarker) const;
    void writeGfa(ostream&, double basesPerMarker) const;

    // Graphviz output.
    void computeVertexLayout(
        uint64_t sizePixels,
        double vertexScalingFactor,
        double edgeLengthPower,
        double edgeLengthScalingFactor,
        double timeout,
        std::map<vertex_descriptor, array<double, 2 > >& vertexPositions
    ) const;
    void writeGraphviz(
        const string& fileName,
        uint64_t sizePixels,
        double vertexScalingFactor,
        double edgeLengthScalingFactor,
        double edgeThicknessScalingFactor,
        double edgeArrowScalingFactor,
        std::map<vertex_descriptor, array<double, 2 > >& vertexPositions) const;
    void writeGraphviz(
        ostream&,
        uint64_t sizePixels,
        double vertexScalingFactor,
        double edgeLengthScalingFactor,
        double edgeThicknessScalingFactor,
        double edgeArrowScalingFactor,
        std::map<vertex_descriptor, array<double, 2 > >& vertexPositions) const;

    // Dump everything to csv files.
    void writeCsv() const;

    // Create a csv file with coloring.
    // If the string passed in is an oriented read,
    // it colors all edges that have that read.
    // If it is the gfaId of an edge, it colors that edge in red
    // and all related edges in green.
    // This can be loaded in Bandage to color the edges.
    void color(
        const string&,
        const string& fileName) const;
    void color(
        const string&,
        ostream&) const;

private:
    void writeCsvEdges() const;
    void writeCsvBubbleChains() const;
    void writeCsvOrientedReadsByEdge() const;
    void writeCsvOrientedReads() const;

    // Create a vertex for each vertex of the assembly graph.
    void createVertices(
        uint64_t vertexCount,
        vector<vertex_descriptor>& vertexTable);

    // Create an edge for each set of parallel edges of the assembly graph.
    void createEdges(
        const AssemblyGraph&,
        const vector<vertex_descriptor>& vertexTable
    );

    // Remove back edges that create reverse bubbles.
    void removeReverseBubbles();

    // Merge linear chains of edges.
    void mergeLinearChains();

    // Assign an id to each edge.
    void assignEdgeIds();

    // Fill in the assembly graph edges that go into each
    // edge of the compressed assembly graph.
    void fillContributingEdges(const AssemblyGraph&);

    // Fill in minimum and maximum marker counts for each edge.
    void fillMarkerCounts(const AssemblyGraph&);

    // Find the oriented reads that appear in marker graph vertices
    // internal to each edge of the compressed assembly graph.
    void findOrientedReads(const Assembler&);

    // The edges that each oriented read appears in.
    // Indexed by OrientedRead::getValue().
    vector< vector<edge_descriptor> > orientedReadTable;
    void fillOrientedReadTable(const Assembler&);

    // Find edges that have at least one common oriented read
    // which each edge.
    void findRelatedEdges();
    void findRelatedEdges(edge_descriptor);

private:
    uint64_t maxPloidy() const;

};

#endif

max_stars_repo_name: AustinHartman/shasta

max_issues_repo_name: AustinHartman/shasta

max_forks_repo_name: AustinHartman/shasta


text:
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
//

#include "stdafx.h"
#include <numeric>
#include <random>
#include <boost/random/uniform_int_distribution.hpp>
#include "NoRandomizer.h"
#include "DataDeserializer.h"
#include "BlockRandomizer.h"
#include "CorpusDescriptor.h"
#include "SequentialDeserializer.h"

using namespace Microsoft::MSR::CNTK;
using namespace std;

namespace Microsoft { namespace MSR { namespace CNTK { namespace Test {

BOOST_AUTO_TEST_SUITE(ReaderLibTests)

class MockChunk : public Chunk
{
private:
    size_t m_chunkBegin;
    size_t m_chunkEnd;
    TensorShapePtr m_sampleLayout;
    uint32_t m_sequenceLength;
    vector<vector<float>>& m_sequenceData;

public:
    MockChunk(size_t chunkBegin, size_t chunkEnd, vector<vector<float>>& sequenceData, uint32_t sequenceLength)
        : m_chunkBegin(chunkBegin),
          m_chunkEnd(chunkEnd),
          m_sampleLayout(make_shared<TensorShape>(1)),
          m_sequenceLength(sequenceLength),
          m_sequenceData(sequenceData)
    {
        assert(chunkBegin <= chunkEnd);
        assert(chunkEnd <= sequenceData.size());
    }

    void GetSequence(size_t sequenceId, vector<SequenceDataPtr>& result) override
    {
        assert(m_chunkBegin <= sequenceId);
        assert(sequenceId < m_chunkEnd);

        auto data = make_shared<MockDenseSequenceData>();
        data->m_data = &m_sequenceData[sequenceId][0];
        data->m_numberOfSamples = m_sequenceLength;
        data->m_sampleLayout = m_sampleLayout;
        result.push_back(data);
    }

    ~MockChunk() override {};
};

class MockDeserializer : public IDataDeserializer
{
private:
    uint32_t m_sequenceLength;
    size_t m_numChunks;
    size_t m_numSequencesPerChunk;
    vector<SequenceDescription> m_descriptions;
    vector<StreamDescriptionPtr> m_streams;
    TensorShapePtr m_sampleLayout;
    vector<ChunkDescriptionPtr> m_chunkDescriptions;
    vector<vector<float>> m_sequenceData;

public:
    MockDeserializer(size_t numChunks, size_t numSequencesPerChunks, vector<float>& data, uint32_t sequenceLength = 1)
        : m_numChunks(numChunks),
          m_numSequencesPerChunk(numSequencesPerChunks),
          m_sampleLayout(make_shared<TensorShape>(1)),
          m_sequenceLength(sequenceLength)
    {
        m_sequenceData.reserve(data.size());
        for (float d : data)
        {
            m_sequenceData.push_back(vector<float>(m_sequenceLength, d));
        }

        size_t numSequences = numChunks * numSequencesPerChunks;
        m_descriptions.reserve(numSequences);
        assert(data.size() == numSequences);

        for (size_t i = 0; i < numSequences; i++)
        {
            m_descriptions.push_back(SequenceDescription {
                i,
                m_sequenceLength,
                (ChunkIdType) (i / m_numSequencesPerChunk),
                { 0, i }
            });
        }

        for (ChunkIdType i = 0; i < numChunks; i++)
        {
            m_chunkDescriptions.push_back(make_shared<ChunkDescription>(ChunkDescription {
                i,
                m_numSequencesPerChunk * m_sequenceLength,
                m_numSequencesPerChunk
            }));
        }

        m_streams.push_back(make_shared<StreamDescription>(StreamDescription{
            L"input",
            0,
            StorageType::dense,
            ElementType::tfloat,
            m_sampleLayout
        }));

    };

    vector<StreamDescriptionPtr> GetStreamDescriptions() const override
    {
        return m_streams;
    }

    virtual ChunkPtr GetChunk(ChunkIdType chunkId) override
    {
        assert(chunkId < m_numChunks);
        size_t chunkBegin = chunkId * m_numSequencesPerChunk;
        size_t chunkEnd = chunkBegin + m_numSequencesPerChunk;
        shared_ptr<Chunk> chunk = make_shared<MockChunk>(chunkBegin, chunkEnd, m_sequenceData, m_sequenceLength);
        return chunk;
    }

    virtual bool GetSequenceDescription(const SequenceDescription&, SequenceDescription&) override
    {
        throw logic_error("Not implemented");
    }

    virtual ChunkDescriptions GetChunkDescriptions() override
    {
        return m_chunkDescriptions;
    }

    virtual void GetSequencesForChunk(ChunkIdType chunkId, vector<SequenceDescription>& descriptions) override
    {
        for (size_t i = chunkId * m_numSequencesPerChunk; i < (chunkId + 1) * m_numSequencesPerChunk; i++)
        {
            descriptions.push_back(SequenceDescription{
                i,
                m_sequenceLength,
                chunkId,
                { 0, i }
            });
        }
    }

    MockDeserializer(const MockDeserializer&) = delete;
    MockDeserializer& operator=(const MockDeserializer&) = delete;
};

void BlockRandomizerInstantiateTest(bool prefetch)
{
    vector<float> data;
    auto mockDeserializer = make_shared<MockDeserializer>(0, 0, data);
    auto randomizer = make_shared<BlockRandomizer>(0, SIZE_MAX, mockDeserializer, prefetch, BlockRandomizer::DecimationMode::chunk, false);
}

BOOST_AUTO_TEST_CASE(CheckGetCurrentCursorForRandomizers)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = chunkSizeInSamples * 5;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    auto blockRandomizer = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);
    auto noRandomizer = make_shared<NoRandomizer>(deserializer, false);

    auto test = [](SequenceEnumeratorPtr r, size_t epochSize)
    {
        auto firstEpoch = ReadFullEpoch(r, epochSize, 0);
        auto firstCursor = r->GetCurrentSamplePosition();
        BOOST_CHECK_EQUAL(firstCursor, firstEpoch.size());

        auto secondEpoch = ReadFullEpoch(r, epochSize, 1);
        auto secondCursor = r->GetCurrentSamplePosition();
        BOOST_CHECK_EQUAL(secondCursor - firstCursor, secondEpoch.size());

        auto thirdEpoch = ReadFullEpoch(r, epochSize, 2);
        auto thirdCursor = r->GetCurrentSamplePosition();
        BOOST_CHECK_EQUAL(thirdCursor - secondCursor, thirdEpoch.size());

        auto anotherSecondEpoch = ReadFullEpoch(r, epochSize, 1);
        auto anotherSecondCursor = r->GetCurrentSamplePosition();

        BOOST_CHECK_EQUAL(anotherSecondCursor, secondCursor);
    };

    // Inside sweep
    size_t epochSize = 50000;
    test(blockRandomizer, epochSize);
    test(noRandomizer, epochSize);

    // Between sweeps
    epochSize = (size_t)(sweepNumberOfSamples / 1.5);
    test(blockRandomizer, epochSize);
    test(noRandomizer, epochSize);
}

BOOST_AUTO_TEST_CASE(CheckSetCurrentCursorForRandomizers)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = chunkSizeInSamples * 5;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    auto expectedBlock = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);
    auto expectedNo = make_shared<NoRandomizer>(deserializer, false);

    auto underTestBlock = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);
    auto unterTestNo = make_shared<NoRandomizer>(deserializer, false);

    auto test = [](SequenceEnumeratorPtr expected, SequenceEnumeratorPtr underTest, size_t epochSize)
    {
        auto firstEpoch = ReadFullEpoch(expected, epochSize, 0);
        auto secondEpoch = ReadFullEpoch(expected, epochSize, 1);
        auto thirdEpoch = ReadFullEpoch(expected, epochSize, 2);

        // First setup the enumerator to ead unbounded amount of data
        EpochConfiguration config;
        config.m_numberOfWorkers = 1;
        config.m_workerRank = 0;
        config.m_minibatchSizeInSamples = 1;
        config.m_totalEpochSizeInSamples = std::numeric_limits<size_t>().max() / 2;
        config.m_epochIndex = 0;
        underTest->StartEpoch(config);

        // Rereading second epoch
        underTest->SetCurrentSamplePosition(firstEpoch.size());
        auto anotherSecond = ReadNextSamples(underTest, secondEpoch.size());
        BOOST_CHECK_EQUAL_COLLECTIONS(
            secondEpoch.begin(),
            secondEpoch.end(),
            anotherSecond.begin(),
            anotherSecond.end());

        // Rereading first epoch
        underTest->SetCurrentSamplePosition(0);
        auto anotherFirst = ReadNextSamples(underTest, firstEpoch.size());
        BOOST_CHECK_EQUAL_COLLECTIONS(
            firstEpoch.begin(),
            firstEpoch.end(),
            anotherFirst.begin(),
            anotherFirst.end());

        // Rereading third epoch
        underTest->SetCurrentSamplePosition(firstEpoch.size() + secondEpoch.size());
        auto anotherThird = ReadNextSamples(underTest, thirdEpoch.size());
        BOOST_CHECK_EQUAL_COLLECTIONS(
            thirdEpoch.begin(),
            thirdEpoch.end(),
            anotherThird.begin(),
            anotherThird.end());
    };

    // Inside sweep
    size_t epochSize = 50000;
    test(expectedBlock, underTestBlock, epochSize);
    test(expectedNo, unterTestNo, epochSize);

    // Between sweeps
    epochSize = (size_t)(sweepNumberOfSamples / 1.5);
    test(expectedBlock, underTestBlock, epochSize);
    test(expectedNo, unterTestNo, epochSize);
}

BOOST_AUTO_TEST_CASE(RandRollbackToEarlierEpochBetweenSweeps)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = chunkSizeInSamples * 5;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    // Let's randomize complete sweep, so that we have a baseline.
    auto randomizer = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);

    // Let's read all sequences from the first three sweeps in the randomized order.
    auto firstSweep = ReadFullSweep(randomizer, 0, sweepNumberOfSamples);
    auto secondSweep = ReadFullSweep(randomizer, 1, sweepNumberOfSamples);
    auto thirdSweep = ReadFullSweep(randomizer, 2, sweepNumberOfSamples);

    // Now let's merge the global timeline of these three sweeps.
    std::vector<float> threeSweeps = Concat(std::vector<vector<float>>{ firstSweep, secondSweep, thirdSweep });

    // Ok, now let's run smaller epochs and check whether they are the same as full sweeps.
    size_t epochSize = threeSweeps.size() / 5;
    auto firstEpoch = ReadFullEpoch(randomizer, epochSize, 0);
    auto secondEpoch = ReadFullEpoch(randomizer, epochSize, 1);
    auto thirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);
    auto fourthEpoch = ReadFullEpoch(randomizer, epochSize, 3);
    auto fifthEpoch = ReadFullEpoch(randomizer, epochSize, 4);
    std::vector<float> anotherThreeSweeps = Concat(std::vector<vector<float>>{ firstEpoch, secondEpoch, thirdEpoch, fourthEpoch, fifthEpoch });

    // Check that data is the same.
    BOOST_CHECK_EQUAL_COLLECTIONS(threeSweeps.begin(), threeSweeps.end(), anotherThreeSweeps.begin(), anotherThreeSweeps.end());

    // Now roll back to the third one.
    auto anotherThirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);

    // Check that it is the same.
    BOOST_CHECK_EQUAL_COLLECTIONS(thirdEpoch.begin(), thirdEpoch.end(), anotherThirdEpoch.begin(), anotherThirdEpoch.end());
}

BOOST_AUTO_TEST_CASE(RandRollbackToEarlierEpochInTheSweep)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = chunkSizeInSamples * 3;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    // Let's randomize complete sweep, so that we have a baseline.
    auto randomizer = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);

    // Let's read all sequences from the first three sweeps in the randomized order.
    auto firstSweep = ReadFullSweep(randomizer, 0, sweepNumberOfSamples);

    // Ok, now let's run smaller epochs and check whether they are the same as full sweeps.
    size_t epochSize = firstSweep.size() / 3;
    auto firstEpoch = ReadFullEpoch(randomizer, epochSize, 0);
    auto secondEpoch = ReadFullEpoch(randomizer, epochSize, 1);
    auto thirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);
    std::vector<float> anotherThreeSweeps = Concat(std::vector<vector<float>>{ firstEpoch, secondEpoch, thirdEpoch });

    // Check that data is the same.
    BOOST_CHECK_EQUAL_COLLECTIONS(firstSweep.begin(), firstSweep.end(), anotherThreeSweeps.begin(), anotherThreeSweeps.end());

    // Now roll back to the second one.
    auto anotherSecondEpoch = ReadFullEpoch(randomizer, epochSize, 1);

    // Check that it is the same.
    BOOST_CHECK_EQUAL_COLLECTIONS(secondEpoch.begin(), secondEpoch.end(), anotherSecondEpoch.begin(), anotherSecondEpoch.end());
}

BOOST_AUTO_TEST_CASE(RandRollbackToSameEpochInTheSweep)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = chunkSizeInSamples * 3;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    // Let's randomize complete sweep, so that we have a baseline.
    auto randomizer = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);

    // Let's read all sequences from the first three sweeps in the randomized order.
    auto firstSweep = ReadFullSweep(randomizer, 0, sweepNumberOfSamples);

    // Ok, now let's run smaller epochs and check whether they are the same as full sweeps.
    size_t epochSize = firstSweep.size() / 4;
    auto firstEpoch = ReadFullEpoch(randomizer, epochSize, 0);
    auto secondEpoch = ReadFullEpoch(randomizer, epochSize, 1);
    auto thirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);

    // Now roll back to the third one.
    auto anotherThirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);

    // Check that it is the same.
    BOOST_CHECK_EQUAL_COLLECTIONS(thirdEpoch.begin(), thirdEpoch.end(), anotherThirdEpoch.begin(), anotherThirdEpoch.end());
}

BOOST_AUTO_TEST_CASE(RandRollbackToSameEpochInBigRandomizationWindow)
{
    size_t chunkSizeInSamples = 10000;
    size_t sweepNumberOfSamples = 500000;
    uint32_t maxSequenceLength = 300;
    size_t randomizationWindow = sweepNumberOfSamples / 2;
    auto deserializer = make_shared<SequentialDeserializer>(0, chunkSizeInSamples, sweepNumberOfSamples, maxSequenceLength);

    // Let's randomize complete sweep, so that we have a baseline.
    auto randomizer = make_shared<BlockRandomizer>(0, randomizationWindow, deserializer, true, BlockRandomizer::DecimationMode::chunk, false);

    // Let's read all sequences from the first three sweeps in the randomized order.
    auto firstSweep = ReadFullSweep(randomizer, 0, sweepNumberOfSamples);

    // Ok, now let's run smaller epochs and check whether they are the same as full sweeps.
    size_t epochSize = firstSweep.size() / 5;
    auto firstEpoch = ReadFullEpoch(randomizer, epochSize, 0);
    auto secondEpoch = ReadFullEpoch(randomizer, epochSize, 1);
    auto thirdEpoch = ReadFullEpoch(randomizer, epochSize, 2);
    auto fourthEpoch = ReadFullEpoch(randomizer, epochSize, 3);

    // Now roll back to the third one.
    auto current = ReadFullEpoch(randomizer, epochSize, 1);
    BOOST_CHECK_EQUAL_COLLECTIONS(secondEpoch.begin(), secondEpoch.end(), current.begin(), current.end());

    current = ReadFullEpoch(randomizer, epochSize, 3);
    BOOST_CHECK_EQUAL_COLLECTIONS(fourthEpoch.begin(), fourthEpoch.end(), current.begin(), current.end());

    current = ReadFullEpoch(randomizer, epochSize, 2);
    BOOST_CHECK_EQUAL_COLLECTIONS(thirdEpoch.begin(), thirdEpoch.end(), current.begin(), current.end());

    current = ReadFullEpoch(randomizer, epochSize, 2);
    BOOST_CHECK_EQUAL_COLLECTIONS(thirdEpoch.begin(), thirdEpoch.end(), current.begin(), current.end());
}

BOOST_AUTO_TEST_CASE(BlockRandomizerInstantiate)
{
    BlockRandomizerInstantiateTest(false);
    BlockRandomizerInstantiateTest(true);
}

void BlockRandomizerOneEpochTest(bool prefetch)
{
    vector<float> data(10);
    iota(data.begin(), data.end(), 0.0f);
    auto mockDeserializer = make_shared<MockDeserializer>(5, 2, data);

    auto randomizer = make_shared<BlockRandomizer>(0, SIZE_MAX, mockDeserializer, prefetch, BlockRandomizer::DecimationMode::chunk, false);

    EpochConfiguration epochConfiguration;
    epochConfiguration.m_numberOfWorkers = 1;
    epochConfiguration.m_workerRank = 0;
    epochConfiguration.m_minibatchSizeInSamples = 0;
    epochConfiguration.m_totalEpochSizeInSamples = data.size();
    epochConfiguration.m_epochIndex = 0;
    randomizer->StartEpoch(epochConfiguration);

    vector<float> expected { 6, 3, 1, 5, 9, 0, 4, 2, 7, 8 };
    BOOST_CHECK_EQUAL(data.size(), expected.size());
    vector<float> actual;
    for (int i = 0; i < data.size() + 1; i++)
    {
        Sequences sequences = randomizer->GetNextSequences(1);
        BOOST_CHECK_EQUAL(sequences.m_data.size(), 1 - (i / data.size()));
        if (i < data.size())
        {
            auto& data2 = reinterpret_cast<DenseSequenceData&>(*sequences.m_data[0][0]);
            BOOST_CHECK_EQUAL(data2.m_numberOfSamples, 1u);
            actual.push_back(*((float*)data2.GetDataBuffer()));
        }
        BOOST_CHECK_EQUAL(sequences.m_endOfEpoch, (data.size() <= i));
    }
    BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
                                  actual.begin(), actual.end());
}

BOOST_AUTO_TEST_CASE(BlockRandomizerOneEpoch)
{
    BlockRandomizerOneEpochTest(false);
    BlockRandomizerOneEpochTest(true);
}

void BlockRandomizerOneEpochWithChunks1Test(bool prefetch)
{
    vector<float> data(10);
    iota(data.begin(), data.end(), 0.0f);
    auto mockDeserializer = make_shared<MockDeserializer>(5, 2, data);

    auto randomizer = make_shared<BlockRandomizer>(0, 4, mockDeserializer, prefetch, BlockRandomizer::DecimationMode::chunk, false);

    EpochConfiguration epochConfiguration;
    epochConfiguration.m_numberOfWorkers = 1;
    epochConfiguration.m_workerRank = 0;
    epochConfiguration.m_minibatchSizeInSamples = 0;
    epochConfiguration.m_totalEpochSizeInSamples = data.size();
    epochConfiguration.m_epochIndex = 0;
    randomizer->StartEpoch(epochConfiguration);

    vector<float> expected{ 8, 9, 1, 0, 6, 7, 2, 3, 4, 5 };
    BOOST_CHECK_EQUAL(data.size(), expected.size());
    vector<float> actual;
    for (int i = 0; i < data.size() + 1; i++)
    {
        Sequences sequences = randomizer->GetNextSequences(1);
        BOOST_CHECK_EQUAL(sequences.m_data.size(), 1 - (i / data.size()));
        if (i < data.size())
        {
            auto& data2 = reinterpret_cast<DenseSequenceData&>(*sequences.m_data[0][0]);
            BOOST_CHECK_EQUAL(data2.m_numberOfSamples, 1u);
            actual.push_back(*((float*)data2.GetDataBuffer()));
        }
        BOOST_CHECK_EQUAL(sequences.m_endOfEpoch, (data.size() <= i));
    }
    BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
        actual.begin(), actual.end());
}

BOOST_AUTO_TEST_CASE(BlockRandomizerOneEpochWithChunks1)
{
    BlockRandomizerOneEpochWithChunks1Test(false);
    BlockRandomizerOneEpochWithChunks1Test(true);
}

void BlockRandomizerOneEpochWithChunks2Test(bool prefetch)
{
    vector<float> data(20);
    iota(data.begin(), data.end(), 0.0f);

    auto mockDeserializer = make_shared<MockDeserializer>(10, 2, data);

    auto randomizer = make_shared<BlockRandomizer>(0, 18, mockDeserializer, prefetch, BlockRandomizer::DecimationMode::chunk, false);

    EpochConfiguration epochConfiguration;
    epochConfiguration.m_numberOfWorkers = 1;
    epochConfiguration.m_workerRank = 0;
    epochConfiguration.m_minibatchSizeInSamples = 0;
    epochConfiguration.m_totalEpochSizeInSamples = data.size();
    epochConfiguration.m_epochIndex = 0;
    randomizer->StartEpoch(epochConfiguration);

    vector<float> expected {
        18, 19, 7, 14, 6, 9, 8, 15, 5, 2,
        10, 13, 16, 17, 1, 4, 3, 12, 11, 0
    };
    BOOST_CHECK_EQUAL(data.size(), expected.size());
    vector<float> actual;
    for (int i = 0; i < data.size() + 1; i++)
    {
        Sequences sequences = randomizer->GetNextSequences(1);
        BOOST_CHECK_EQUAL(sequences.m_data.size(), 1 - (i / data.size()));
        if (i < data.size())
        {
            auto& data2 = reinterpret_cast<DenseSequenceData&>(*sequences.m_data[0][0]);
            BOOST_CHECK_EQUAL(data2.m_numberOfSamples, 1u);
            actual.push_back(*((float*)data2.GetDataBuffer()));
        }
        BOOST_CHECK_EQUAL(sequences.m_endOfEpoch, (data.size() <= i));
    }
    BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
        actual.begin(), actual.end());
}

BOOST_AUTO_TEST_CASE(BlockRandomizerOneEpochWithChunks2)
{
    BlockRandomizerOneEpochWithChunks2Test(false);
    BlockRandomizerOneEpochWithChunks2Test(true);
}

void BlockRandomizerChaosMonkeyTest(bool prefetch)
{
    const int sequenceLength = 3;
    const int seed = 42;
    const int numChunks = 100;
    const int numSequencesPerChunk = 10;
    const int windowSize = 18;
    vector<float> data(numChunks * numSequencesPerChunk);
    iota(data.begin(), data.end(), 0.0f);
    std::mt19937 rng(seed);
    boost::random::uniform_int_distribution<int> distr(1, 10);

    auto mockDeserializer = make_shared<MockDeserializer>(numChunks, numSequencesPerChunk, data, sequenceLength);

    auto randomizer = make_shared<BlockRandomizer>(0, windowSize, mockDeserializer, prefetch, BlockRandomizer::DecimationMode::chunk, false);

    for (int t = 0; t < 100; t++)
    {
        EpochConfiguration epochConfiguration;
        epochConfiguration.m_numberOfWorkers = distr(rng);
        do
        {
            epochConfiguration.m_workerRank = distr(rng) - 1;
        }
        while (epochConfiguration.m_numberOfWorkers <= epochConfiguration.m_workerRank);

        epochConfiguration.m_minibatchSizeInSamples = 0; // don't care
        epochConfiguration.m_totalEpochSizeInSamples = data.size() / distr(rng);
        epochConfiguration.m_epochIndex = distr(rng);
        randomizer->StartEpoch(epochConfiguration);

        int samplesToGet = 0;
        for (int i = 0; i < epochConfiguration.m_totalEpochSizeInSamples + 1; i += samplesToGet)
        {
            samplesToGet = distr(rng);
            Sequences sequences = randomizer->GetNextSequences(samplesToGet);

            // In case end of epoch/decimation/single sequence -> skip the mbSize check.
            if (sequences.m_endOfEpoch || sequences.m_data.empty() || sequences.m_data.front().size() < 2)
            {
                continue;
            }

            // Check that we do not exceed the minibatch size.
            size_t count = 0;
            for (const auto& sequence : sequences.m_data.front())
            {
                count += sequence->m_numberOfSamples;
            }
            BOOST_CHECK_LE(count, samplesToGet);
        }
    }
}

BOOST_AUTO_TEST_CASE(BlockRandomizerChaosMonkey)
{
    BlockRandomizerChaosMonkeyTest(false);
    BlockRandomizerChaosMonkeyTest(true);
}

void BlockRandomizerOneEpochLegacyRandomizationTest(bool prefetch)
{
    vector<float> data(10);
    iota(data.begin(), data.end(), 0.0f);
    auto mockDeserializer = make_shared<MockDeserializer>(5, 2, data);

    auto randomizer = make_shared<BlockRandomizer>(0,
        SIZE_MAX,
        mockDeserializer,
        prefetch,
        BlockRandomizer::DecimationMode::sequence,
        true);

    EpochConfiguration epochConfiguration;
    epochConfiguration.m_numberOfWorkers = 1;
    epochConfiguration.m_workerRank = 0;
    epochConfiguration.m_minibatchSizeInSamples = 0;
    epochConfiguration.m_totalEpochSizeInSamples = data.size();
    epochConfiguration.m_epochIndex = 0;
    randomizer->StartEpoch(epochConfiguration);

    vector<float> expected { 6, 3, 1, 5, 9, 0, 4, 2, 7, 8 };
    BOOST_CHECK_EQUAL(data.size(), expected.size());
    vector<float> actual;
    for (int i = 0; i < data.size() + 1; i++)
    {
        Sequences sequences = randomizer->GetNextSequences(1);
        BOOST_CHECK_EQUAL(sequences.m_data.size(), 1 - (i / data.size()));
        if (i < 10)
        {
            auto& data2 = reinterpret_cast<DenseSequenceData&>(*sequences.m_data[0][0]);
            BOOST_CHECK_EQUAL(data2.m_numberOfSamples, 1u);
            actual.push_back(*((float*)data2.GetDataBuffer()));

        }
        BOOST_CHECK_EQUAL(sequences.m_endOfEpoch, (data.size() <= i));
    }
    BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
                                  actual.begin(), actual.end());
}

BOOST_AUTO_TEST_CASE(BlockRandomizerOneEpochLegacyRandomization)
{
    BlockRandomizerOneEpochLegacyRandomizationTest(false);
    BlockRandomizerOneEpochLegacyRandomizationTest(true);
}

BOOST_AUTO_TEST_CASE(NoRandomizerOneEpoch)
{
    vector<float> data(10);
    iota(data.begin(), data.end(), 0.0f);
    auto mockDeserializer = make_shared<MockDeserializer>(5, 2, data);

    auto randomizer = make_shared<NoRandomizer>(mockDeserializer);

    EpochConfiguration epochConfiguration;
    epochConfiguration.m_numberOfWorkers = 1;
    epochConfiguration.m_workerRank = 0;
    epochConfiguration.m_minibatchSizeInSamples = 0;
    epochConfiguration.m_totalEpochSizeInSamples = data.size();
    epochConfiguration.m_epochIndex = 0;
    randomizer->StartEpoch(epochConfiguration);

    // Note: for NoRandomizer, end-of-epoch is only returned if there's no data.

    vector<float> actual;
    for (int i = 0; i < data.size() + 2; i++)
    {
        Sequences sequences = randomizer->GetNextSequences(1);
        BOOST_CHECK_EQUAL(sequences.m_data.size(), 1 - (i / data.size()));
        if (i < data.size())
        {
            auto& data2 = reinterpret_cast<DenseSequenceData&>(*sequences.m_data[0][0]);
            BOOST_CHECK_EQUAL(data2.m_numberOfSamples, 1u);
            actual.push_back(*((float*)data2.GetDataBuffer()));
        }

        BOOST_CHECK_EQUAL(sequences.m_endOfEpoch, (data.size() <= i));
    }

    BOOST_CHECK_EQUAL_COLLECTIONS(data.begin(), data.end(),
                                  actual.begin(), actual.end());
}

BOOST_AUTO_TEST_CASE(DefaultCorpusDescriptor)
{
    const int seed = 13;
    std::mt19937 rng(seed);
    boost::random::uniform_int_distribution<int> distr(50, 60);

    string randomKey(10, (char)distr(rng));

    CorpusDescriptor corpus(false);
    BOOST_CHECK_EQUAL(true, corpus.IsIncluded(randomKey));
    BOOST_CHECK_EQUAL(true, corpus.IsIncluded(""));
}

BOOST_AUTO_TEST_CASE(NumericCorpusDescriptor)
{
    const int seed = 13;
    std::mt19937 rng(seed);
    boost::random::uniform_int_distribution<size_t> distr;

    CorpusDescriptor corpus(true);
    for (int i = 0; i < 10; ++i)
    {
        auto value = distr(rng);
        BOOST_CHECK_EQUAL(value, corpus.KeyToId(std::to_string(value)));
    }
    BOOST_CHECK_EXCEPTION(
        corpus.KeyToId("not a number"),
        std::exception,
        [](const std::exception& e) { return e.what() == std::string("Invalid numeric sequence id 'not a number'"); });
}

BOOST_AUTO_TEST_CASE(LiteralCorpusDescriptor)
{
    const int seed = 13;
    std::mt19937 rng(seed);
    boost::random::uniform_int_distribution<int> distr(50, 60);

    string randomKey(10, (char)distr(rng));

    CorpusDescriptor corpus(false);
    BOOST_CHECK(100 != corpus.KeyToId("100"));
    BOOST_CHECK_NO_THROW(corpus.KeyToId("not a number"));
}

BOOST_AUTO_TEST_CASE(CorpusDescriptorFromFile)
{
    FILE* test = fopen("test.tmp", "w+");
    fwrite("1\n", sizeof(char), 2, test);
    fwrite("2\n", sizeof(char), 2, test);
    fwrite("4\n", sizeof(char), 2, test);
    fclose(test);

    CorpusDescriptor corpus(L"test.tmp", true);
    BOOST_CHECK_EQUAL(false, corpus.IsIncluded("0"));
    BOOST_CHECK_EQUAL(true, corpus.IsIncluded("1"));
    BOOST_CHECK_EQUAL(true, corpus.IsIncluded("2"));
    BOOST_CHECK_EQUAL(false, corpus.IsIncluded("3"));
    BOOST_CHECK_EQUAL(true, corpus.IsIncluded("4"));
    BOOST_CHECK_EQUAL(false, corpus.IsIncluded("5"));

    remove("test.tmp");
}

BOOST_AUTO_TEST_SUITE_END()

} } } }

ext: cpp

max_stars_repo_name: atfkaka/CNTK

max_issues_repo_name: atfkaka/CNTK

max_forks_repo_name: atfkaka/CNTK


text:
//
// OpenTissue, A toolbox for physical based simulation and animation.
// Copyright (C) 2007 Department of Computer Science, University of Copenhagen
//
#include <OpenTissue/configuration.h>

#include <OpenTissue/core/math/math_basic_types.h>
#include <OpenTissue/collision/continuous/continuous_default_motion_policy.h>
#include <OpenTissue/collision/gjk/gjk_support_functors.h>

#define BOOST_AUTO_TEST_MAIN
#include <OpenTissue/utility/utility_push_boost_filter.h>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/test_tools.hpp>
#include <OpenTissue/utility/utility_pop_boost_filter.h>

#include <cmath>

using namespace OpenTissue;

BOOST_AUTO_TEST_SUITE(opentissue_collision_continuous_default_motion_policy);

BOOST_AUTO_TEST_CASE(case_by_case_test)
{
  typedef OpenTissue::math::BasicMathTypes<double, size_t> math_types;
  typedef math_types::vector3_type                         V;
  typedef math_types::real_type                            T;
  typedef math_types::quaternion_type                      Q;
  typedef math_types::coordsys_type                        X;

  X from;
  X to;

  from.identity();
  to.T() = V(1.0,2.0,3.0);
  to.Q().Ru( 3.0, V(1.0,0.0,0.0) );
  V v;
  V w;
  OpenTissue::collision::continuous::DefaultMotionPolicy::compute_velocities( from, to, 1.0, v, w);

  BOOST_CHECK_CLOSE( v(0), to.T()(0), 0.01 );
  BOOST_CHECK_CLOSE( v(1), to.T()(1), 0.01 );
  BOOST_CHECK_CLOSE( v(2), to.T()(2), 0.01 );
  BOOST_CHECK_CLOSE( w(0), 3.0, 0.01 );
  BOOST_CHECK_CLOSE( w(1), 0.0, 0.01 );
  BOOST_CHECK_CLOSE( w(2), 0.0, 0.01 );

  T tau = 0.5;
  X cur = OpenTissue::collision::continuous::DefaultMotionPolicy::integrate_motion(from, tau, v, w);

  BOOST_CHECK_CLOSE( 0.5, cur.T()(0), 0.01 );
  BOOST_CHECK_CLOSE( 1.0, cur.T()(1), 0.01 );
  BOOST_CHECK_CLOSE( 1.5, cur.T()(2), 0.01 );

  T theta;
  V n;
  OpenTissue::math::get_axis_angle( cur.Q(), n, theta );

  BOOST_CHECK_CLOSE( theta, 1.5, 0.01 );
  BOOST_CHECK_CLOSE( n(0), 1.0, 0.01 );
  BOOST_CHECK_CLOSE( n(1), 0.0, 0.01 );
  BOOST_CHECK_CLOSE( n(2), 0.0, 0.01 );

  OpenTissue::gjk::Sphere<math_types> const A;
  OpenTissue::gjk::Sphere<math_types> const B;
  X X_a;
  X X_b;

  X_a.T() = V(-2.0,0.0,0.0);
  X_a.Q().identity();

  X_b.T() = V( 2.0,0.0,0.0);
  X_b.Q().identity();

  V p_a;
  V p_b;

  OpenTissue::collision::continuous::DefaultMotionPolicy::compute_closest_points( X_a, A, X_b, B, p_a, p_b);

  BOOST_CHECK_CLOSE( p_a(0), -1.0, 0.1);
  BOOST_CHECK_CLOSE( p_a(1),  0.0, 0.1);
  BOOST_CHECK_CLOSE( p_a(2),  0.0, 0.1);

  BOOST_CHECK_CLOSE( p_b(0),  1.0, 0.1);
  BOOST_CHECK_CLOSE( p_b(1),  0.0, 0.1);
  BOOST_CHECK_CLOSE( p_b(2),  0.0, 0.1);

}

BOOST_AUTO_TEST_SUITE_END();

max_stars_repo_name: ricortiz/OpenTissue

max_issues_repo_name: ricortiz/OpenTissue

max_forks_repo_name: ricortiz/OpenTissue


text:
#pragma once

#include <stdexcept>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include "gphoto_if.hpp"
#include "gphoto_exceptions.hpp"

using namespace boost::python;

void translateException(const std::runtime_error& x) {
  std::string message = std::string("GPhotoException: ") + x.what();
  PyErr_SetString(PyExc_UserWarning, message.c_str());
};

/// \brief Defines which functions and classes are exported to Python.
BOOST_PYTHON_MODULE(gphoto_if) {
  register_exception_translator<GPhotoException>(translateException);

  class_<StringList>("StringList")
        .def(vector_indexing_suite<StringList>() );

  class_<GPhotoIf>("GPhotoIf", init<std::string, std::string, bool>())
        .def("getSummary", &GPhotoIf::getSummary)
        .def("getFilenamesFromFolder", &GPhotoIf::getFilenamesFromFolder)
        .def("getFoldernamesFromFolder", &GPhotoIf::getFoldernamesFromFolder)
        .def("downloadFile", &GPhotoIf::downloadFile)
    ;
}

ext: hpp

max_stars_repo_name: bachmmmar/PTPIPCameraSync

max_issues_repo_name: bachmmmar/PTPIPCameraSync

max_forks_repo_name: bachmmmar/PTPIPCameraSync


text:
#include "../include/simple_fft/fft_settings.h"

// boost::multi_aray uses square brackets for indices
#ifndef __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR
#define __USE_SQUARE_BRACKETS_FOR_ELEMENT_ACCESS_OPERATOR
#endif

#include "../include/simple_fft/fft.h"
#include "test_fft.h"
#include <iostream>
#include <boost/multi_array.hpp>

namespace simple_fft {
namespace fft_test {

int testBoostMultiArray()
{
    std::cout << "Testing FFT algorithms with boost::multi_array" << std::endl;

    using namespace pulse_params;

    std::vector<real_type> t, x, y;
    makeGridsForPulse3D(t, x, y);

    // typedefing arrays
    typedef boost::multi_array<real_type,1> RealArray1D;
    typedef boost::multi_array<complex_type,1> ComplexArray1D;
    typedef boost::multi_array<real_type,2> RealArray2D;
    typedef boost::multi_array<complex_type,2> ComplexArray2D;
    typedef boost::multi_array<real_type,3> RealArray3D;
    typedef boost::multi_array<complex_type,3> ComplexArray3D;

    // 1D fields and spectrum
    RealArray1D E1_real(boost::extents[nt]);
    ComplexArray1D E1_complex(boost::extents[nt]), G1(boost::extents[nt]),
                   E1_restored(boost::extents[nt]);

    // 2D fields and spectrum
    RealArray2D E2_real(boost::extents[nt][nx]);
    ComplexArray2D E2_complex(boost::extents[nt][nx]), G2(boost::extents[nt][nx]),
                   E2_restored(boost::extents[nt][nx]);

    // 3D fields and spectrum
    RealArray3D E3_real(boost::extents[nt][nx][ny]);
    ComplexArray3D E3_complex(boost::extents[nt][nx][ny]), G3(boost::extents[nt][nx][ny]),
                   E3_restored(boost::extents[nt][nx][ny]);

    if (!commonPartsForTests3D(E1_real, E2_real, E3_real, E1_complex, E2_complex,
                               E3_complex, G1, G2, G3, E1_restored, E2_restored,
                               E3_restored, t, x, y))
    {
        std::cout << "Tests of FFT with boost::multi_array returned with errors!"
                  << std::endl;
        return FAILURE;
    }

    std::cout << "Tests of FFT with boost::multi_array completed successfully!" << std::endl;
    return SUCCESS;
}

} // namespace fft_test
} // namespace simple_fft

max_stars_repo_name: opalcompany/Simple-FFT

max_issues_repo_name: opalcompany/Simple-FFT

max_forks_repo_name: opalcompany/Simple-FFT


text:
/*
 Copyright (C) 2016 by Wojciech Jaśkowski, Michał Kempka, Grzegorz Runc, Jakub Toczek, Marek Wydmuch

 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 <boost/interprocess/ipc/message_queue.hpp>
#include <boost/thread.hpp>

#include "vizdoom_main.h"
#include "vizdoom_defines.h"
#include "vizdoom_input.h"
#include "vizdoom_game.h"
#include "vizdoom_screen.h"
#include "vizdoom_shared_memory.h"
#include "vizdoom_message_queue.h"

#include "d_main.h"
#include "d_net.h"

namespace b = boost;
namespace bt = boost::this_thread;

CVAR (Bool, vizdoom_controlled, false, CVAR_NOSET)
CVAR (Bool, vizdoom_async, false, CVAR_NOSET)
CVAR (String, vizdoom_instance_id, "0", CVAR_NOSET)
CVAR (Int, vizdoom_screen_format, 0, CVAR_NOSET)
CVAR (Bool, vizdoom_no_console, false, CVAR_NOSET)
CVAR (Bool, vizdoom_no_sound, false, CVAR_NOSET)
CVAR (Bool, vizdoom_window_hidden, false, CVAR_NOSET)
CVAR (Bool, vizdoom_no_x_server, false, CVAR_NOSET)
CVAR (Bool, vizdoom_allow_input, false, CVAR_NOSET)
CVAR (Bool, vizdoom_nocheat, false, CVAR_NOSET)

int vizdoom_time = 0;
bool vizdoomNextTic = false;
bool vizdoomUpdate = false;
unsigned int vizdoomLastUpdate = 0;

void ViZDoom_Init(){
    Printf("ViZDoom_Init: Instance id: %s\n", *vizdoom_instance_id);

    if(*vizdoom_controlled) {
        Printf("ViZDoom_Init: Init message queues\n");
        ViZDoom_MQInit(*vizdoom_instance_id);

        Printf("ViZDoom_Init: Init shared memory\n");
        ViZDoom_SMInit(*vizdoom_instance_id);

        ViZDoom_InputInit();
        ViZDoom_GameVarsInit();

        ViZDoom_ScreenInit();

        vizdoomNextTic = true;
        vizdoomUpdate = true;
    }
}

void ViZDoom_Close(){
    if(*vizdoom_controlled) {
        ViZDoom_InputClose();
        ViZDoom_GameVarsClose();
        ViZDoom_ScreenClose();

        ViZDoom_SMClose();
        ViZDoom_MQClose();
    }
}

void ViZDoom_AsyncStartTic(){
    try{
        bt::interruption_point();
    }
    catch(b::thread_interrupted &ex ){
        exit(0);
    }

    if (*vizdoom_controlled && !ViZDoom_IsPaused()){
        ViZDoom_MQTic();
        if(vizdoomNextTic) ViZDoom_InputTic();
    }
}

void ViZDoom_Tic(){

    try{
        bt::interruption_point();
    }
    catch(b::thread_interrupted &ex ){
        exit(0);
    }

    if (*vizdoom_controlled && !ViZDoom_IsPaused()){

        NetUpdate();

        if(vizdoomUpdate) {
            ViZDoom_Update();
        }
        if(vizdoomNextTic) {
            ViZDoom_GameVarsTic();
            ViZDoom_MQSend(VIZDOOM_MSG_CODE_DOOM_DONE);
            vizdoomNextTic = false;
        }

        if(!*vizdoom_async){
            ViZDoom_MQTic();
            ViZDoom_InputTic();
        }
    }
}

void ViZDoom_Update(){
    D_Display();
    ViZDoom_ScreenUpdate();
    vizdoomLastUpdate = VIZDOOM_TIME;
    vizdoomUpdate = false;
}

bool ViZDoom_IsPaused(){
    return menuactive != MENU_Off;

    //&& (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE)
    //&& !paused && !pauseext && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling
}

max_stars_repo_name: xakiru/doom-py

max_issues_repo_name: xakiru/doom-py

max_forks_repo_name: xakiru/doom-py


text: #include <boost/mpl/vector/aux_/clear.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
// Header file we're implementing
#include "MeshUtils.hpp"

// std
#include <algorithm>

// External libs
#include <Eigen/Geometry>
#include <LinearMath/btConvexHull.h>
#include <voro++.hh>

// Project-local
#include "Logger.hpp"

// icosphere code https://github.com/MicBosi/VisualizationLibrary
// LICENSE:
/*
   Visualization Library
http://visualizationlibrary.org

Copyright (c) 2005-2011, Michele Bosi
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
noob::mesh_3d noob::mesh_utils::sphere(float radius, uint32_t detail_arg)
{
	const float X = 0.525731112119133606;
	const float Z = 0.850650808352039932;

	std::vector<noob::vec3f> verts;

	verts.push_back(noob::vec3f(-X, 0.0, Z));
	verts.push_back(noob::vec3f(X, 0.0, Z));
	verts.push_back(noob::vec3f(-X, 0.0, -Z));
	verts.push_back(noob::vec3f(X, 0.0, -Z));
	verts.push_back(noob::vec3f(0.0, Z, X));
	verts.push_back(noob::vec3f(0.0, Z, -X));
	verts.push_back(noob::vec3f(0.0, -Z, X));
	verts.push_back(noob::vec3f(0.0, -Z, -X));
	verts.push_back(noob::vec3f(Z, X, 0.0));
	verts.push_back(noob::vec3f(-Z, X, 0.0));
	verts.push_back(noob::vec3f(Z, -X, 0.0));
	verts.push_back(noob::vec3f(-Z, -X, 0.0));

	uint32_t idxs[] = {
		1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4,
		1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2,
		3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0,
		10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7 };

	std::vector<uint32_t> indices;
	for(uint32_t i = 0; i < 4*5*3; ++i)
	{
		indices.push_back(idxs[i]);
	}

	// Triangulate the icosahedron
	const uint32_t detail = std::min(static_cast<uint32_t>(8), detail_arg);

	for(int i=0; i < detail; ++i)
	{
		std::vector<uint32_t> indices2;
		std::vector<noob::vec3f> verts2;
		for(uint32_t j = 0, idx = 0; j < indices.size(); j += 3)
		{
			indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
			indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
			indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);
			indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++);

			noob::vec3f v1 = verts[ indices[j+0] ]; v1 = noob::normalize(v1);
			noob::vec3f v2 = verts[ indices[j+1] ]; v2 = noob::normalize(v2);
			noob::vec3f v3 = verts[ indices[j+2] ]; v3 = noob::normalize(v3);

			noob::vec3f a = (v1 + v2) * 0.5f; a = noob::normalize(a);
			noob::vec3f b = (v2 + v3) * 0.5f; b = noob::normalize(b);
			noob::vec3f c = (v3 + v1) * 0.5f; c = noob::normalize(c);

			verts2.push_back(v1); verts2.push_back(a); verts2.push_back(c);
			verts2.push_back(a); verts2.push_back(v2); verts2.push_back(b);
			verts2.push_back(a); verts2.push_back(b); verts2.push_back(c);
			verts2.push_back(c); verts2.push_back(b); verts2.push_back(v3);
		}
		verts = verts2;
		indices = indices2;
	}

	noob::mesh_3d results;

	// results.position.reserve(verts.size());
	// results.normal.reserve(verts.size());
	// results.indices.reserve(indices.size());

	for (uint32_t i = 0; i < verts.size(); ++i)
	{
		noob::mesh_3d::vert vv;
		vv.position = verts[i] * radius;
		vv.normal = noob::normalize(verts[i]);
		vv.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);

		results.vertices.push_back(vv);

	}

	for(uint32_t i : indices)
	{
		results.indices.push_back(i);
	}

	//	results.bbox.min = noob::vec3f(-radius, -radius, -radius);
	//	results.bbox.max = noob::vec3f(radius, radius, radius);

	results.calculate_dims();
	return results;
}

// Box code adapted from https://github.com/danginsburg/opengles3-book/blob/master/Common/Source/esShapes.c
// I recommend anyone serious about OpenGLES get a copy of Dan Ginsburg's excellent book!
//
// Book:      OpenGL(R) ES 3.0 Programming Guide, 2nd Edition
// Authors:   Dan Ginsburg, Budirijanto Purnomo, Dave Shreiner, Aaftab Munshi
// ISBN-10:   0-321-93388-5
// ISBN-13:   978-0-321-93388-1
// Publisher: Addison-Wesley Professional
// URLs:      http://www.opengles-book.com
//            http://my.safaribooksonline.com/book/animation-and-3d/9780133440133
//
// License below:

// The MIT License (MIT)
//
// Copyright (c) 2013 Dan Ginsburg, Budirijanto Purnomo
//
// 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.

noob::mesh_3d noob::mesh_utils::box(float width, float height, float depth)
{
	const uint32_t num_vertices = 24;
	const uint32_t num_indices = 36;

	noob::mesh_3d results;
	/*
	   noob::vec3f point_a(-0.5*width, 0.5*height, -0.5*depth);
	   noob::vec3f point_b(0.5*width, 0.5*height, -0.5*depth);
	   noob::vec3f point_c(0.5*width, 0.5*height, 0.5*depth);
	   noob::vec3f point_d(-0.5*width, 0.5*height, 0.5*depth);
	   noob::vec3f point_e(-0.5*width, -0.5*height, -0.5*depth);
	   noob::vec3f point_f(0.5*width, -0.5*height, -0.5*depth);
	   noob::vec3f point_g(0.5*width, -0.5*height, 0.5*depth);
	   noob::vec3f point_h(-0.5*width, -0.5*height, 0.5*depth);

	   results.position.push_back(point_a);
	   results.position.push_back(point_b);
	   results.position.push_back(point_c);
	   results.verts.push_back(point_d);
	   results.push_back(point_e);
	   results.push_back(point_f);
	   results.push_back(point_g);
	   results.push_back(point_h);

	 */

	const float cube_verts[] =
	{
		-0.5f * width, -0.5f * height, -0.5f * depth,
		-0.5f * width, -0.5f * height,  0.5f * depth,
		0.5f * width, -0.5f * height,  0.5f * depth,
		0.5f * width, -0.5f * height, -0.5f * depth,
		-0.5f * width,  0.5f * height, -0.5f * depth,
		-0.5f * width,  0.5f * height,  0.5f * depth,
		0.5f * width,  0.5f * height,  0.5f * depth,
		0.5f * width,  0.5f * height, -0.5f * depth,
		-0.5f * width, -0.5f * height, -0.5f * depth,
		-0.5f * width,  0.5f * height, -0.5f * depth,
		0.5f * width,  0.5f * height, -0.5f * depth,
		0.5f * width, -0.5f * height, -0.5f * depth,
		-0.5f * width, -0.5f * height, 0.5f * depth,
		-0.5f * width,  0.5f * height, 0.5f * depth,
		0.5f * width,  0.5f * height, 0.5f * depth,
		0.5f * width, -0.5f * height, 0.5f * depth,
		-0.5f * width, -0.5f * height, -0.5f * depth,
		-0.5f * width, -0.5f * height,  0.5f * depth,
		-0.5f * width,  0.5f * height,  0.5f * depth,
		-0.5f * width,  0.5f * height, -0.5f * depth,
		0.5f * width, -0.5f * height, -0.5f * depth,
		0.5f * width, -0.5f * height,  0.5f * depth,
		0.5f * width,  0.5f * height,  0.5f * depth,
		0.5f * width,  0.5f * height, -0.5f * depth,
	};

	const float cube_normals[] =
	{
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
	};

	for (uint32_t i = 0; i < num_vertices * 3; i += 3)
	{
		noob::mesh_3d::vert vv;

		vv.position = noob::vec3f(cube_verts[i], cube_verts[i + 1], cube_verts[i + 2]);
		vv.normal = noob::vec3f(cube_normals[i], cube_normals[i + 1], cube_normals[i + 2]);
		vv.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);

		results.vertices.push_back(vv);
	}

	/*
	   const float cube_tex[] =
	   {
	   0.0f, 0.0f,
	   0.0f, 1.0f,
	   1.0f, 1.0f,
	   1.0f, 0.0f,
	   1.0f, 0.0f,
	   1.0f, 1.0f,
	   0.0f, 1.0f,
	   0.0f, 0.0f,
	   0.0f, 0.0f,
	   0.0f, 1.0f,
	   1.0f, 1.0f,
	   1.0f, 0.0f,
	   0.0f, 0.0f,
	   0.0f, 1.0f,
	   1.0f, 1.0f,
	   1.0f, 0.0f,
	   0.0f, 0.0f,
	   0.0f, 1.0f,
	   1.0f, 1.0f,
	   1.0f, 0.0f,
	   0.0f, 0.0f,
	   0.0f, 1.0f,
	   1.0f, 1.0f,
	   1.0f, 0.0f,
	   };

	   for (uint32_t i = 0; i < num_vertices * 2; i += 2)
	   {
	   results.position[i/2].texcoords = noob::vec3f(cube_tex[i], cube_tex[i+1], 0);
	   }
	 */
	const uint32_t cube_indices[] =
	{
		0, 2, 1,
		0, 3, 2,
		4, 5, 6,
		4, 6, 7,
		8, 9, 10,
		8, 10, 11,
		12, 15, 14,
		12, 14, 13,
		16, 17, 18,
		16, 18, 19,
		20, 23, 22,
		20, 22, 21
	};

	for (uint32_t i = 0; i < num_indices; ++i)
	{
		results.indices.push_back(cube_indices[i]);
	}

	results.bbox.min = noob::vec3f(-0.5f * width, -0.5f * height, -0.5f * depth);
	results.bbox.max = noob::vec3f(0.5f * width, 0.5f * height, 0.5f * depth);

	return results;
}

// This code is adapted from http://www.songho.ca/opengl/gl_cylinder.html
noob::mesh_3d noob::mesh_utils::cylinder(float radius, float height, uint32_t segments, bool narrowed_end, float narrow_to) {
	// Generate a unit circle on XY-plane
	const float PI = 3.1415926f;
	const float sector_step = 2 * PI / static_cast<float>(segments);
	float sector_angle;  // radians

	noob::mesh_3d results;
	std::vector<noob::vec3f> unit_circle_vertices;
	for(int i = 0; i <= segments; ++i)
	{
		sector_angle = i * sector_step;
		unit_circle_vertices.push_back(noob::vec3f(std::cos(sector_angle), std::sin(sector_angle), 0.0));
	}

	for(int i = 0; i < 2; ++i)
	{
		const float h = -height / 2.0f + i * height;           // z value; -h/2 to h/2
		const float t = 1.0f - i;                              // vertical tex coord; 1 to 0

		const bool narrow_me = (i == 0 && narrowed_end);
		for(uint32_t j = 0, k = 0; j <= segments; ++j)
		{

			noob::vec3f temp = unit_circle_vertices[j];
			const float ux = temp.v[0];
			const float uy = temp.v[1];
			const float uz = temp.v[2];

			noob::mesh_3d::vert v;
			if (narrow_me)
			{
				v.position = noob::vec3f(ux * std::fabs(narrow_to), uy * fabs(narrow_to), h);
			} else
			{
				v.position = noob::vec3f(ux * radius, uy * radius, h);
			}
			v.normal = noob::vec3f(ux, uy, uz);
			v.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);
			v.texcoords = noob::vec3f(static_cast<float>(j) / static_cast<float>(segments), t, 0.0);

			results.vertices.push_back(v);

		}
	}

	// The starting index for the base/top surface
	// NOTE: It is used for generating indices later
	uint32_t base_center_index = results.vertices.size();
	uint32_t top_center_index = base_center_index + segments + 1;

	// Put base and top vertices to arrays
	for (uint32_t i = 0; i < 2; ++i)
	{
		const bool narrow_me = (i == 0 && narrowed_end);

		float h = -height / 2.0f + static_cast<float>(i) * height;
		float nz = -1.0 + static_cast<float>(i) * 2.0;

		noob::mesh_3d::vert center;
		// Center point
		center.position = noob::vec3f(0.0, 0.0, h);
		center.normal = noob::vec3f(0.0, 0.0, nz);
		center.texcoords = noob::vec3f(0.5, 0.5, 0.0);
		center.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);
		results.vertices.push_back(center);

		for (uint32_t j = 0, k = 0; j < segments; ++j)
		{

			float ux = unit_circle_vertices[j].v[0];
			float uy = unit_circle_vertices[j].v[1];
			noob::mesh_3d::vert v;

			if (narrow_me)
			{
				v.position = noob::vec3f(ux * narrow_to, uy * narrow_to, h);
			}
			else
			{
				v.position = noob::vec3f(ux * radius, uy * radius, h);
			}

			v.normal = noob::vec3f(0.0, 0.0, nz);
			v.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);
			v.texcoords = noob::vec3f(-ux * 0.5 + 0.5, -uy * 0.5f + 0.5f, 0.0);
			results.vertices.push_back(v);
		}
	}

	uint32_t k1 = 0;
	uint32_t k2 = segments + 1;

	// Indices for the side surface
	for(uint32_t i = 0; i < segments; ++i, ++k1, ++k2)
	{
		// 2 triangles per sector
		// k1 => k1+1 => k2
		results.indices.push_back(k1);
		results.indices.push_back(k1 + 1);
		results.indices.push_back(k2);

		// k2 => k1+1 => k2+1
		results.indices.push_back(k2);
		results.indices.push_back(k1 + 1);
		results.indices.push_back(k2 + 1);
	}

	// Indices for the base surface
	for(uint32_t i = 0, k = base_center_index + 1; i < segments; ++i, ++k)
	{
		if(i < segments - 1)
		{
			results.indices.push_back(base_center_index);
			results.indices.push_back(k + 1);
			results.indices.push_back(k);
		}
		else // Last triangle
		{
			results.indices.push_back(base_center_index);
			results.indices.push_back(base_center_index + 1);
			results.indices.push_back(k);
		}
	}

	// Indices for the top surface
	for(int i = 0, k = top_center_index + 1; i < segments; ++i, ++k)
	{
		if(i < segments - 1)
		{
			results.indices.push_back(top_center_index);
			results.indices.push_back(k);
			results.indices.push_back(k + 1);
		}
		else // Last triangle
		{
			results.indices.push_back(top_center_index);
			results.indices.push_back(k);
			results.indices.push_back(top_center_index + 1);
		}
	}

	return results;

}

noob::mesh_3d noob::mesh_utils::cone(float radius, float height, uint32_t segments)
{
	return cylinder(radius, height, segments, true, 0.0);
}

/*
   noob::mesh_3d noob::mesh_utils::voro(float width, float height, float depth)
   {
   const double x = width * 0.5;
   const double y = height * 0.5;
   const double z = depth * 0.5;

   voro::voronoicell cell;
   cell.init(-x, x, -y, y, -z, z);

   noob::mesh_3d results;

   std::vector<double> verts;
   cell.vertices(verts);

   std::vector<double> face_normals;
   cell.normals(face_normals);

   std::vector<int> face_orders;
   cell.face_orders(face_orders);

   std::vector<int> face_vert_indices;
   cell.face_vertices(face_vert_indices);

// Using the number of values in face_order to tell us how many faces we have.
for (uint32_t i = 0; i < face_orders.size(); ++i)
{

}

results.bbox.min = noob::vec3f(-x, -y, -z);
results.bbox.max = noob::vec3f(x, y, z);

return results;

}
 */

/*
   noob::mesh_3d noob::mesh_utils::cone(float radius, float height, uint32_t segments_arg)
   {
   const float half_height = height * 0.5;
   const uint32_t segments = std::max(segments_arg, static_cast<uint32_t>(3));

   noob::mesh_3d top = noob::mesh_utils::circle(radius, segments);
   noob::mesh_3d bottom = noob::mesh_utils::circle(radius, segments);

   const uint32_t num_verts = top.vertices.size();
   const uint32_t num_indices = top.indices.size();

   {
   fmt::MemoryWriter ww;
   ww << "[MeshUtils] Cone mesh circles verts = " << num_verts << ", indices = " << num_indices;
   logger::log(ww.str());
   }
// Position our vertices

top.vertices[0] = noob::vec3f(0.0, half_height, 0.0);
bottom.vertices[0] = noob::vec3f(0.0, -half_height, 0.0);

for (uint32_t i = 1; i < num_verts; ++i)
{
noob::vec3f temp(top.vertices[i]);
temp[1] = -half_height;
top.vertices[i] = temp;
bottom.vertices[i] = temp;
}

// Now, we split the triangles on the top mesh, in order to be able to give each vertex its normal

noob::mesh_3d results;

const uint32_t num_split_verts = num_verts * 3;

results.position.resize(num_split_verts + num_verts);
results.normal.resize(num_split_verts + num_verts);
results.indices.resize(num_indices * 2);

const noob::vec3f top_origin = top.vertices[0];

for (uint32_t i = 0; i < num_verts; i += 2)
{
results.position[i * 3] = top_origin;
results.position[(i * 3) + 1] = top.vertices[i];
results.position[(i * 3) + 2] = top.vertices[i + 1];
}

// Now, calculate the normals: TODO:
for (uint32_t i = 0; i < num_verts; i += 2)
{
const noob::vec3f first = top.vertices[i] - top_origin;
const noob::vec3f second = top.vertices[i+1] - top_origin;
const noob::vec3f n = noob::normalize(noob::cross(first, second));

results.normal[i * 3] = n;
results.normal[(i * 3) + 1] = n;
results.normal[(i * 3) + 2] = n;
}

// Now, add our bottom to the results
const uint32_t total_verts = results.position.size();
for (uint32_t i = num_split_verts; i < total_verts; ++i)
{
results.position[i] = bottom.vertices[i - num_split_verts];
results.normal[i] = noob::vec3f(0.0, -1.0, 0.0);
}
const uint32_t total_indices = results.indices.size();
for (uint32_t i = num_indices; i < total_indices; ++i)
{
results.indices[i] = bottom.indices[i-num_indices];
}

// std::fill(bottom.normals.begin(), bottom.normals.end(), noob::vec3f(0.0, -1.0, 0.0));

results.bbox.min = noob::vec3f(-radius, -half_height, -radius);
results.bbox.max = noob::vec3f(radius, half_height, radius);

return results;
}

noob::mesh_3d noob::mesh_utils::cylinder(float radius, float height, uint32_t segments)
{
	// TODO: Implement!
	return noob::mesh_utils::cone(radius, height, segments);
}
*/

noob::mesh_3d noob::mesh_utils::hull(const std::vector<noob::vec3f>& points)
{
	// TODO: Optimize this
	std::vector<btVector3> bt_points;

	noob::mesh_3d mesh;

	noob::bbox_type<float> accum;
	for (noob::vec3f p : points)
	{
		accum.min[0] = std::min(accum.min[0], p[0]);
		accum.min[1] = std::min(accum.min[1], p[1]);
		accum.min[2] = std::min(accum.min[2], p[2]);

		accum.max[0] = std::max(accum.max[0], p[0]);
		accum.max[1] = std::max(accum.max[1], p[1]);
		accum.max[2] = std::max(accum.max[2], p[2]);

		bt_points.push_back(btVector3(p[0], p[1], p[2]));
	}

	mesh.bbox = accum;//.max - accum.min;//noob::vec3f();//accum.max + accum.min

	HullDesc hull_desc(QF_DEFAULT, points.size(), &bt_points[0]);

	HullLibrary hull_lib;
	HullResult hull_result;

	HullError error_msg = hull_lib.CreateConvexHull(hull_desc, hull_result);

	if (error_msg == HullError::QE_FAIL)
	{
		logger::log(noob::importance::ERROR, "FAILED TO CREATE CONVEX HULL. WTF?");
	}

	for (uint32_t i = 0; i < hull_result.mNumOutputVertices; ++i)
	{
		noob::mesh_3d::vert vv;
		vv.position = noob::vec3f_from_bullet(hull_result.m_OutputVertices[i]);
		vv.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);
		mesh.vertices.push_back(vv);
	}

	for (uint32_t i = 0; i < hull_result.mNumIndices; ++i)
	{
		mesh.indices.push_back(static_cast<uint16_t>(hull_result.m_Indices[i]));
	}

	return mesh;
}

noob::mesh_3d noob::mesh_utils::circle(float radius, uint32_t segments_arg)
{
	const uint32_t segments = std::max(segments_arg, static_cast<uint32_t>(3));
	const float increment_amount = NOOB_TWO_PI / segments;
	const Eigen::Vector3f p(radius, 0.0, radius);

	noob::mesh_3d results;
	//results.position.reserve(segments + 1);
	// results.normal.reserve(segments + 1);
	const uint32_t num_indices = segments * 3;
	// results.indices.reserve(num_indices);

	// std::fill(results.normal.begin(), results.normal.end(), noob::vec3f(0.0, 1.0, 0.0));

	noob::mesh_3d::vert vv;

	vv.normal = noob::vec3f(0.0, 1.0, 0.0);
	vv.position = noob::vec3f(0.0, 0.0, 0.0);
	vv.colour = noob::vec4f(1.0, 1.0, 1.0, 1.0);

	results.vertices.push_back(vv);

	for (uint32_t seg = 1; seg < segments; ++seg)
	{
		const float diff = increment_amount * static_cast<float>(seg);
		const Eigen::AngleAxis<float> angle_axis(diff, Eigen::Vector3f::UnitY());
		const Eigen::Vector3f rotated_point = angle_axis * p;
		vv.position = noob::vec3f_from_eigen(rotated_point);
		results.vertices.push_back(vv);
	}

	uint32_t accum = 1;;
	for (uint32_t i = 0; i < num_indices; i += 3)
	{
		results.indices.push_back(0);
		results.indices.push_back(accum);
		++accum;
		results.indices.push_back(accum);
	}

	results.bbox.min = noob::vec3f(-radius, 0.0, -radius);
	results.bbox.max = noob::vec3f(radius, 0.0 , radius);

	return results;
}

max_stars_repo_name: ColinGilbert/noobwerkz-engine

max_issues_repo_name: ColinGilbert/noobwerkz-engine-borked

max_forks_repo_name: ColinGilbert/noobwerkz-engine-borked


text:
// This file defines an useful iterator over the cartesian product of iterable
// containers, that is, provides a single iterator that iterates over all
// combinations of elements given in the arguments.
//
// This allows integration with methods that require iterators and reduces the
// number of loops in the code.
//
// As writing the class type may be hard, a helper function is provided. The
// iterator returned iterates over the containers, left to right, and provides a
// method get_end() to get the end iterator associated with it.
//
// Example:
// vector<int> c1({1,2});
// vector<char> c2({'a','b'});
// auto it = make_product_iterator(c1, c2);
// auto end = it.get_end();
// for (; it != end; ++it) {
//   // Provides a std::tuple<int,char> with the values from the constructor
//   *it;
//   // Access to a single element of the tuple is optimized and the following
//   // comparison always holds
//   it.get<0>() == std::get<0>(*it);
// }

#ifndef __PRODUCT_ITERATOR_HPP__
#define __PRODUCT_ITERATOR_HPP__

#include <boost/iterator/iterator_facade.hpp>
#include <tuple>
#include <type_traits>

template <class... Containers>
class product_iterator:
  public boost::iterator_facade<
    product_iterator<Containers...>,
    std::tuple<
      typename std::remove_reference<
        typename Containers::value_type
      >::type const&...
    > const,
    boost::forward_traversal_tag
  > {
    private:
      typedef std::tuple<
        typename std::remove_reference<
          typename Containers::value_type
        >::type const&...
      > value_type;

      typedef std::tuple<
        typename Containers::const_iterator...
      > iterator_type;

      // Helper structs for tuple expanding
      template <size_t...> struct sequence {};
      template <size_t N, size_t... S>
      struct sequence_generator: sequence_generator<N-1, N-1, S...> {};
      template <size_t... S>
      struct sequence_generator<0, S...> {
        typedef sequence<S...> type;
      };
      template <class T>
      struct tuple_sequence_generator {
        typedef typename sequence_generator<std::tuple_size<T>::value>::type
          type;
      };

    public:
      product_iterator();

      product_iterator(product_iterator const& other);

      product_iterator(Containers const&... containers);

      ~product_iterator();

      product_iterator const& operator=(product_iterator const& other);

      // Gets the end iterator to be compared
      product_iterator<Containers...> get_end() const;

      // See public get() member bellow private section

    private:
      // Boost stuff due to facade
      friend class boost::iterator_core_access;
      void increment();
      bool equal(product_iterator<Containers...> const& other) const;
      value_type const& dereference() const;

      // Helper method to dereference. Just get references from each iterator
      // and builds a tuple of constant references.
      template <size_t... S> value_type make_value_type(sequence<S...>) const;

      // Auxiliary methods to constructor to copy iterators to tuple
      template <size_t I, class T1, class... Types>
      void copy_iterator(T1 const& container, Types const&... containers);
      template <size_t I, class T1>
      void copy_iterator(T1 const& container);

      // Auxiliary method to increment() to increment each iterator
      template <size_t I>
      void advance(typename std::enable_if<(I == 0), int>::type = 0);
      template <size_t I>
      void advance(typename std::enable_if<(I > 0), int>::type = 0);

      // Holds iterators to each container used at construction
      iterator_type current_, begin_, end_;

      // Holds the last tuple created by operator*, so that it can be returned
      // in multiple calls if the iterator is the same. This variable if freed
      // in operator++ and the destructor.
      // We must use this so that we can return a const& at operator* to comply
      // with the range-based for
      // for (auto& it : product)
      // If it could be "auto it", then we wouldn't need to keep reallocating
      // this thing. We also can't keep a single copy because each element of
      // the tuple is a const&, so it can't be constructed by itself.
      mutable value_type* current_tuple_;

    public:
      // Enables access to a single value instead of the whole tuple. This
      // method is preffered to the operator* as it doesn't require tuple
      // construction. Behaves like std::get<I>(*iterator).
      template <size_t I>
      auto get() const -> decltype(*std::get<I>(current_)) {
        // This function must come after the private section as it needs
        // `current_` to be defined before it for use in the trailing return
        // type.

        // As only a single value is needed, gathers it from its iterator.
        return *std::get<I>(current_);
      }
};

template <class... Containers>
product_iterator<Containers...>
make_product_iterator(Containers const&... containers) {
  return product_iterator<Containers...>(containers...);
}

#include "product_iterator_impl.hpp"

#endif

max_stars_repo_name: mirandaconrado/product-iterator

max_issues_repo_name: mirandaconrado/product-iterator

max_forks_repo_name: mirandaconrado/product-iterator


text:
#include "UDPServer.h"

#include <boost/bind/bind.hpp>
#include <iostream>
#include <string>

void UDPServer::insert_client(const ServerSideUDPClient& client) {
    auto iter = std::find(m_clients.begin(), m_clients.end(), client);
    if (iter == m_clients.end()) {
        m_clients.push_back(client);
    }
}

void UDPServer::start_receive() {
    SharedPtr<std::array<char, s_max_message_size>> ptr(new std::array<char, s_max_message_size> { 0 });
    ServerSideUDPClient client(new udp::endpoint);
    m_socket.async_receive_from(boost::asio::buffer(*ptr),
        *client.endpoint,
        boost::bind(&UDPServer::handle_receive,
            this,
            ptr,
            client,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}

void UDPServer::handle_send(SharedPtr<std::array<char, s_max_message_size>> msg,
    const boost::system::error_code& error,
    size_t) {
    ASSERT(!error);
    // report("sent: _{}_", std::string(msg->data(), strlen(msg->data())));
}

void UDPServer::handle_receive(SharedPtr<std::array<char, s_max_message_size>> msg,
    ServerSideUDPClient client,
    const boost::system::error_code& error,
    size_t size) {
    if (!error) {
        insert_client(client);
        // report("got msg from {}, {}: _{}_", client.endpoint->address(), client.endpoint->port(), std::string(msg->data()));
        SharedPtr<std::array<char, s_max_message_size>> message(new std::array<char, s_max_message_size> { 0 });
        if (on_receive) {
            auto maybe_msg = on_receive(client, msg, size);
            if (!maybe_msg.has_value()) {
                message = nullptr;
            } else {
                *message = maybe_msg.value();
            }
        } else if (simple_on_receive) {
            msg->at(size) = 0;
            std::string str(msg->data());
            auto maybe_msg_as_str = simple_on_receive(client, str, size);
            if (!maybe_msg_as_str.has_value()) {
                message = nullptr;
            } else {
                std::string MessageAsStr = maybe_msg_as_str.value();
                std::copy(MessageAsStr.begin(), MessageAsStr.end(), message->begin());
            }
        }
        if (message) {
            m_socket.async_send_to(boost::asio::buffer(*message),
                *client.endpoint,
                boost::bind(&UDPServer::handle_send, this,
                    message,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
        }
        start_receive();
    }
}

UDPServer::UDPServer(uint16_t port)
    : m_socket(m_io, udp::endpoint(udp::v4(), port)) {
    start_receive();
}

void UDPServer::send_to_all(SharedPtr<std::array<char, s_max_message_size>> data, size_t) {
    report("i know of {} client(s).", m_clients.size());
    for (auto& client : m_clients) {
        m_socket.async_send_to(boost::asio::buffer(*data),
            *client.endpoint,
            boost::bind(&UDPServer::handle_send, this,
                data,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }
}

void UDPServer::send_to_all(SharedPtr<std::array<char, s_max_message_size>> data, size_t, ServerSideUDPClient ignore) {
    report("i know of {} client(s).", m_clients.size());
    for (auto& client : m_clients) {
        if (client == ignore) {
            continue;
        }
        m_socket.async_send_to(boost::asio::buffer(*data),
            *client.endpoint,
            boost::bind(&UDPServer::handle_send, this,
                data,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }
}

void UDPServer::send_to(SharedPtr<std::array<char, s_max_message_size>> data, size_t, ServerSideUDPClient target) {
    m_socket.async_send_to(boost::asio::buffer(*data),
        *target.endpoint,
        boost::bind(&UDPServer::handle_send, this,
            data,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}

void UDPServer::run() {
    std::thread processing([&] { m_io.run(); });
    processing.join();
}


text:
// Copyright © 2017-2020 Khaos Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

#include "Signer.h"

#include "../Hash.h"
#include "../uint256.h"
#include <boost/multiprecision/cpp_int.hpp>

using namespace TW;
using namespace TW::Aion;

Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept {
    using boost::multiprecision::uint128_t;

    auto key = PrivateKey(Data(input.private_key().begin(), input.private_key().end()));
    auto transaction = Transaction(
        /* nonce: */ static_cast<uint128_t>(load(input.nonce())),
        /* gasPrice: */ static_cast<uint128_t>(load(input.gas_price())),
        /* gasLimit: */ static_cast<uint128_t>(load(input.gas_limit())),
        /* to: */ Address(input.to_address()),
        /* amount: */ static_cast<uint128_t>(load(input.amount())),
        /* timestamp */ static_cast<uint128_t>(input.timestamp()),
        /* payload: */ Data(input.payload().begin(), input.payload().end()));
    Signer::sign(key, transaction);

    auto output = Proto::SigningOutput();
    auto encoded = transaction.encode();
    output.set_encoded(encoded.data(), encoded.size());
    output.set_signature(transaction.signature.data(), transaction.signature.size());
    return output;
}

void Signer::sign(const PrivateKey& privateKey, Transaction& transaction) noexcept {
    auto encoded = transaction.encode();
    auto hashData = Hash::blake2b(encoded, 32);
    auto hashSignature = privateKey.sign(hashData, TWCurveED25519);
    auto publicKeyData = privateKey.getPublicKey(TWPublicKeyTypeED25519).bytes;

    // Aion signature = pubKeyBytes + signatureBytes
    Data result(publicKeyData.begin(), publicKeyData.end());
    result.insert(result.end(), hashSignature.begin(), hashSignature.end());

    transaction.signature = result;
}

max_stars_repo_name: Khaos-Labs/khaos-wallet-core

max_issues_repo_name: Khaos-Labs/khaos-wallet-core

max_forks_repo_name: Khaos-Labs/khaos-wallet-core


text:
#include "DefaultStatisticsRepository.h"

#include "gtest/gtest.h"

#include "StatisticsStorageMock.h"
#include <boost/optional/optional_io.hpp>

using namespace ::testing;
using namespace glossary::statisticsRepository;

namespace
{
const EnglishWord englishWord1{"englishWord1"};
const EnglishWord englishWord2{"englishWord2"};
const EnglishWord nonExistingWord{"nonExistingWord"};
const WordStatistics wordStats1{englishWord1, 7, 0};
const WordStatistics wordStats2{englishWord2, 8, 0};
const Statistics oneWordStatistics{wordStats1};
const Statistics twoWordsStatistics{wordStats1, wordStats2};
}

class DefaultStatisticsRepositoryTest : public Test
{
public:
    std::unique_ptr<StatisticsStorageMock> storageInit =
        std::make_unique<StrictMock<StatisticsStorageMock>>();
    StatisticsStorageMock* storage = storageInit.get();
    DefaultStatisticsRepository repository{std::move(storageInit)};
};

TEST_F(DefaultStatisticsRepositoryTest, addWordStatistics)
{
    EXPECT_CALL(*storage, addWordStatistics(wordStats1));

    repository.addWordStatistics(wordStats1);
}

TEST_F(DefaultStatisticsRepositoryTest, getWordStatistics)
{
    EXPECT_CALL(*storage, getWordStatistics(englishWord1)).WillOnce(Return(wordStats1));

    const auto actualWordStats = repository.getWordStatistics(englishWord1);

    ASSERT_EQ(actualWordStats, wordStats1);
}

TEST_F(DefaultStatisticsRepositoryTest, getStatistics)
{
    EXPECT_CALL(*storage, getStatistics()).WillOnce(Return(twoWordsStatistics));

    const auto statistics = repository.getStatistics();

    ASSERT_EQ(statistics, twoWordsStatistics);
}

TEST_F(DefaultStatisticsRepositoryTest, englishWordInStorage_shouldAddCorrectAnswer)
{
    EXPECT_CALL(*storage, contains(englishWord1)).WillOnce(Return(true));
    EXPECT_CALL(*storage, addCorrectAnswer(englishWord1));

    repository.addCorrectAnswer(englishWord1);
}

TEST_F(DefaultStatisticsRepositoryTest, englishWordNotInStorage_shouldAddEmptyWordAndThenAddCorrectAnswer)
{
    EXPECT_CALL(*storage, contains(englishWord1)).WillOnce(Return(false));
    EXPECT_CALL(*storage, addWordStatistics(WordStatistics{englishWord1, 0, 0}));
    EXPECT_CALL(*storage, addCorrectAnswer(englishWord1));

    repository.addCorrectAnswer(englishWord1);
}

TEST_F(DefaultStatisticsRepositoryTest, englishWordInStorage_shouldAddIncorrectAnswer)
{
    EXPECT_CALL(*storage, contains(englishWord1)).WillOnce(Return(true));
    EXPECT_CALL(*storage, addIncorrectAnswer(englishWord1));

    repository.addIncorrectAnswer(englishWord1);
}

TEST_F(DefaultStatisticsRepositoryTest, englishWordNotInStorage_shouldAddEmptyWordAndThenAddIncorrectAnswer)
{
    EXPECT_CALL(*storage, contains(englishWord1)).WillOnce(Return(false));
    EXPECT_CALL(*storage, addWordStatistics(WordStatistics{englishWord1, 0, 0}));
    EXPECT_CALL(*storage, addIncorrectAnswer(englishWord1));

    repository.addIncorrectAnswer(englishWord1);
}

TEST_F(DefaultStatisticsRepositoryTest, resetStatistics)
{
    EXPECT_CALL(*storage, resetStatistics());

    repository.resetStatistics();
}

max_stars_repo_name: michalovsky/Glossary

max_issues_repo_name: michalovsky/Glossary

max_forks_repo_name: michalovsky/Glossary


text:
#include <armadillo>

#include "UnitarySparseMatrix.h"

struct NewBasisDecomposition::Impl {
    std::vector<arma::sp_vec> sparse_vectors;

  public:
    Impl() = default;
};

NewBasisDecomposition::NewBasisDecomposition() : pImpl {std::make_unique<Impl>()} {}
NewBasisDecomposition::~NewBasisDecomposition() = default;
NewBasisDecomposition::NewBasisDecomposition(NewBasisDecomposition&&) noexcept = default;
NewBasisDecomposition& NewBasisDecomposition::operator=(NewBasisDecomposition&&) noexcept = default;

struct IteratorImpl: public NewBasisDecomposition::Iterator {
    arma::SpMat<double>::col_iterator iter;
    const arma::SpMat<double>::col_iterator end;

    IteratorImpl(arma::SpMat<double>::col_iterator iter1, arma::SpMat<double>::col_iterator iter2) :
        iter(iter1),
        end(iter2) {}

    bool hasNext() const override {
        return iter != end;
    }

    IndexValueItem getNext() override {
        auto pair = iter;
        ++iter;
        return {static_cast<uint32_t>(pair.row()), *pair};
    }

    ~IteratorImpl() = default;
};

std::unique_ptr<NewBasisDecomposition::Iterator>
NewBasisDecomposition::GetNewIterator(size_t index_of_vector) const {
    return std::make_unique<IteratorImpl>(
        pImpl->sparse_vectors[index_of_vector].begin_col(0),
        pImpl->sparse_vectors[index_of_vector].end_col(0));
}

std::ostream& operator<<(std::ostream& os, const NewBasisDecomposition& decomposition) {
    for (const auto& v : decomposition.pImpl->sparse_vectors) {
        os << v << std::endl;
    }
    return os;
}

uint32_t NewBasisDecomposition::size() const {
    return pImpl->sparse_vectors.size();
}

bool NewBasisDecomposition::empty() const {
    return pImpl->sparse_vectors.empty();
}

bool NewBasisDecomposition::vempty(uint32_t index_of_vector) const {
    return pImpl->sparse_vectors[index_of_vector].n_nonzero == 0;
}

void NewBasisDecomposition::clear() {
    pImpl->sparse_vectors.clear();
}

void NewBasisDecomposition::move_vector_from(
    uint32_t i,
    NewBasisDecomposition& decomposition_from) {
    pImpl->sparse_vectors.emplace_back(std::move(decomposition_from.pImpl->sparse_vectors[i]));
}

void NewBasisDecomposition::move_all_from(NewBasisDecomposition& decomposition_from) {
    for (uint32_t i = 0; i < decomposition_from.size(); ++i) {
        move_vector_from(i, decomposition_from);
    }
}

void NewBasisDecomposition::copy_vector_from(
    uint32_t i,
    const NewBasisDecomposition& decomposition_from) {
    pImpl->sparse_vectors.emplace_back(decomposition_from.pImpl->sparse_vectors[i]);
}

void NewBasisDecomposition::copy_all_from(const NewBasisDecomposition& decomposition_from) {
    for (uint32_t i = 0; i < decomposition_from.size(); ++i) {
        copy_vector_from(i, decomposition_from);
    }
}

void NewBasisDecomposition::add_to_position(double value, uint32_t i, uint32_t j) {
    pImpl->sparse_vectors[i][j] += value;
}

double NewBasisDecomposition::operator()(uint32_t i, uint32_t j) const {
    return pImpl->sparse_vectors[i][j];
}

void NewBasisDecomposition::resize(uint32_t new_size) {
    pImpl->sparse_vectors.resize(new_size, arma::SpCol<double>(tensor_size));
}

bool NewBasisDecomposition::is_zero(uint32_t i, uint32_t j) const {
    // TODO: epsilon
    return std::abs(pImpl->sparse_vectors[i][j]) < 0.001;
}

void NewBasisDecomposition::erase_if_zero() {
    for (auto& sp_v : pImpl->sparse_vectors) {
        // TODO: epsilon
        for (auto i = sp_v.begin(); i != sp_v.end(); ++i) {
            if (std::abs(*i) < 0.001) {
                *i = 0;
            }
        }
    }
}

// TODO: test if it is really works
void NewBasisDecomposition::normalize() {
    for (auto& v : pImpl->sparse_vectors) {
        double norm = arma::norm(v);
        for (auto&& el : v) {
            el /= norm;
        }
    }
}


text:
#ifndef AWARE_ANDROID_SERVICE_HPP
#define AWARE_ANDROID_SERVICE_HPP

///////////////////////////////////////////////////////////////////////////////
//
// http://github.com/breese/aware
//
// Copyright (C) 2013 Bjorn Reese <breese@users.sourceforge.net>
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
///////////////////////////////////////////////////////////////////////////////

#include <map>

#include <boost/asio/io_service.hpp>

#include <jni.h>

#include <aware/android/detail/client.hpp>

namespace aware
{
namespace android
{

class announce_socket;
class monitor_socket;

class service : public boost::asio::io_service::service
{
public:
    static boost::asio::io_service::id id;

    struct implementation_type
    {
    };

    service(boost::asio::io_service& io, JNIEnv* env, jobject awareObject);
    service(boost::asio::io_service& io);

    void construct(implementation_type&) {}
    void destroy(implementation_type&) {}

    const detail::client& get_client() const { return client; }

private:
    virtual void shutdown_service() {}

private:
    detail::client client;
};

} // namespace avahi
} // namespace aware

#endif // AWARE_ANDROID_SERVICE_HPP

max_stars_repo_name: xpgdk/aware

max_issues_repo_name: xpgdk/aware

max_forks_repo_name: xpgdk/aware


text: #include <boost/hana/ext/boost/mpl/list.hpp>