text:
// test_nonce.cpp -- Test sodium::nonce<>
//
// ISC License
//
// Copyright (c) 2018 Farid Hajji <farid@hajji.name>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE sodium::nonce Test
#include <boost/test/included/unit_test.hpp>

#include "nonce.h"

struct SodiumFixture
{
    SodiumFixture()
    {
        BOOST_REQUIRE(sodium_init() != -1);
        // BOOST_TEST_MESSAGE("SodiumFixture(): sodium_init() successful.");
    }
    ~SodiumFixture()
    {
        // BOOST_TEST_MESSAGE("~SodiumFixture(): teardown -- no-op.");
    }
};

BOOST_FIXTURE_TEST_SUITE(sodium_test_suite, SodiumFixture)

BOOST_AUTO_TEST_CASE(sodium_test_nonce_defaultsize)
{
    sodium::nonce<> a{};

    BOOST_CHECK_EQUAL(a.size(), sodium::NONCESIZE_SECRETBOX);
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_size)
{
    sodium::nonce<64> a{};
    sodium::nonce<128> b{};

    BOOST_CHECK_EQUAL(a.size(), 64);
    BOOST_CHECK_EQUAL(b.size(), 128);

    static_assert(a.size() == 64, "a is not 64 bytes long");
    static_assert(b.size() == 128, "b is not 128 bytes long");
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_copy)
{
    sodium::nonce<> a{};
    sodium::nonce<> a_copy{ a };

    BOOST_CHECK(a == a_copy); // check operator== in constant time
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_move)
{
    sodium::nonce<> a{};
    sodium::nonce<> a_copy{ a };
    sodium::nonce<> a_move1{ std::move(a_copy) };

    // create a copy of a in a temporary object,
    // then implicitely move (not copy) it into a_move2.
    sodium::nonce<> a_move2{ sodium::nonce<>(a) };

    BOOST_CHECK(a == a_move1); // check operator== in constant time
    BOOST_CHECK(a == a_move2);
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_assignment)
{
    sodium::nonce<64> a{};
    sodium::nonce<64> b{};

    BOOST_CHECK(a !=
                b); // may fail in very rare cases (1 out of 2^{8*64} cases)
    a = b;
    BOOST_CHECK(a == b);
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_increment_compare)
{
    sodium::nonce<> a{};
    sodium::nonce<> a_copy{ a };

    BOOST_CHECK(a == a_copy);    // check operator==
    BOOST_CHECK(!(a != a_copy)); // check operator!=

    BOOST_CHECK(!(a < a_copy)); // check operator<
    BOOST_CHECK(!(a > a_copy)); // check operator>

    BOOST_CHECK(a <= a_copy); // check operator<=
    BOOST_CHECK(a >= a_copy); // check operator>=

    BOOST_CHECK_EQUAL(sodium::compare(a, a_copy), 0);

    for (int i : { 1, 2, 3, 4, 5 }) {
        static_cast<void>(i); // "use" unused variable i
        a.increment();
    }

    // The compare checks, except for == and !=, may fail in rare
    // cases, if wrap around occurs. But that is rare with the
    // nonces having the default number of bytes.

    BOOST_CHECK(!(a == a_copy));
    BOOST_CHECK(a != a_copy);

    BOOST_CHECK(a > a_copy);
    BOOST_CHECK(a_copy < a);

    BOOST_CHECK(a >= a_copy);
    BOOST_CHECK(!(a <= a_copy));

    BOOST_CHECK_EQUAL(sodium::compare(a, a_copy), 1);
    BOOST_CHECK_EQUAL(sodium::compare(a_copy, a), -1);
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_pre_post_increment_compare)
{
    sodium::nonce<> a{};
    sodium::nonce<> a_copy1{ a };
    sodium::nonce<> a_copy2{ a };
    sodium::nonce<> a_copy3{ a };

    sodium::nonce<> one{ false }; // start with 0
    one.increment();              // and make it 1 with increment()
    sodium::nonce<> a_plus_one{ a_copy3 += one };

    // now test ++a and a++:
    sodium::nonce<> a_plus_plus{ a_copy1++ };
    sodium::nonce<> plus_plus_a{ ++a_copy2 };

    // pre-increment is always different from post-increment
    BOOST_CHECK(a_plus_plus != plus_plus_a);

    // pre-increment is indeed original value+1
    BOOST_CHECK(plus_plus_a == a_plus_one);

    // pre-increment has indeed incremented original value (by 1)
    BOOST_CHECK(a_copy1 == a_plus_one);

    // post-increment returns original value
    BOOST_CHECK(a_plus_plus == a);

    // post-increment has indeed incremented original value (by 1)
    BOOST_CHECK(a_copy2 == a_plus_one);

    // This fails in case of wrap-around (very rare, we don't care):
    BOOST_CHECK(a_plus_plus < plus_plus_a);
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_init_nonzero)
{
    sodium::nonce<> a{};

    // In rare cases, this check could fail, because all-zeroes is a
    // valid initial nonce value. It can happen once in every
    // 2^{8*Sodium::NONCESIZE_SECRETBOX} cases.

    BOOST_CHECK(!a.is_zero());
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_init_zero)
{
    sodium::nonce<> a(false); // non-initialized nonce...

    BOOST_CHECK(a.is_zero()); // ... must be all-zeroes.
}

BOOST_AUTO_TEST_CASE(sodium_test_nonce_operator_plus_equal)
{
    sodium::nonce<128> a{};
    sodium::nonce<128> b{ a };
    sodium::nonce<128> five(false); // all-zeroes

    BOOST_CHECK(a == b);

    // 1. increment 'a' and 'five' 5 times:
    for (int i : { 1, 2, 3, 4, 5 }) {
        static_cast<void>(i); // "use" unused variable i
        a.increment();
        five.increment();
    }

    // 2. add 'five' to 'b' with += operator (in constant time)
    b += five;

    // 3. a+5 == b+5
    BOOST_CHECK(a == b);
}

BOOST_AUTO_TEST_SUITE_END()


text:
// Copyright 2015, 2020 Peter Dimov
// Copyright 2020 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/mp11/tuple.hpp>
#include <boost/mp11/detail/config.hpp>

// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++

#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )

int main() {}

#else

#include <tuple>
#include <utility>

constexpr int f( int x )
{
    return x + 1;
}

constexpr int g( int x, int y )
{
    return x + y + 1;
}

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

int main()
{
    {
        constexpr std::tuple<int, int, int> tp( 1, 2, 3 );

        constexpr auto r = boost::mp11::tuple_transform( f, tp );

        STATIC_ASSERT( r == std::make_tuple( 2, 3, 4 ) );
    }

    {
        constexpr std::tuple<int, int> tp1( 1, 2 );
        constexpr std::pair<int, int> tp2( 3, 4 );

        constexpr auto r = boost::mp11::tuple_transform( g, tp1, tp2 );

        STATIC_ASSERT( r == std::make_tuple( 5, 7 ) );
    }

#if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 9
// "error: default initialization of an object of const type 'const std::tuple<>' without a user-provided default constructor"
#else

    {
        constexpr std::tuple<> tp;
        constexpr std::tuple<> r = boost::mp11::tuple_transform( f, tp );
        (void)r;
    }

#endif
}

#endif

ext: cpp


text:
//
// $Id$
//
//
// Original author: Darren Kessner <darren@proteowizard.org>
//
// Copyright 2008 Spielberg Family Center for Applied Proteomics
//   Cedars-Sinai Medical Center, Los Angeles, California  90048
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#define PWIZ_SOURCE

#include "ChromatogramList_Thermo.hpp"

#ifdef PWIZ_READER_THERMO
#include "Reader_Thermo_Detail.hpp"
#include "pwiz/utility/misc/Filesystem.hpp"
#include "pwiz/utility/misc/Std.hpp"
#include <boost/bind.hpp>
#include <boost/range/algorithm/for_each.hpp>

using namespace pwiz::cv;

namespace pwiz {
namespace msdata {
namespace detail {

using namespace Thermo;

ChromatogramList_Thermo::ChromatogramList_Thermo(const MSData& msd, RawFilePtr rawfile, const Reader::Config& config)
:   msd_(msd), rawfile_(rawfile), indexInitialized_(util::init_once_flag_proxy), config_(config)
{
}

PWIZ_API_DECL size_t ChromatogramList_Thermo::size() const
{
    boost::call_once(indexInitialized_.flag, boost::bind(&ChromatogramList_Thermo::createIndex, this));
    return index_.size();
}

PWIZ_API_DECL const ChromatogramIdentity& ChromatogramList_Thermo::chromatogramIdentity(size_t index) const
{
    boost::call_once(indexInitialized_.flag, boost::bind(&ChromatogramList_Thermo::createIndex, this));
    if (index>size())
        throw runtime_error(("[ChromatogramList_Thermo::chromatogramIdentity()] Bad index: "
                            + lexical_cast<string>(index)).c_str());
    return reinterpret_cast<const ChromatogramIdentity&>(index_[index]);
}

PWIZ_API_DECL size_t ChromatogramList_Thermo::find(const string& id) const
{
    boost::call_once(indexInitialized_.flag, boost::bind(&ChromatogramList_Thermo::createIndex, this));
    map<string, size_t>::const_iterator itr = idMap_.find(id);
    if (itr != idMap_.end())
        return itr->second;

    return size();
}

PWIZ_API_DECL ChromatogramPtr ChromatogramList_Thermo::chromatogram(size_t index, bool getBinaryData) const
{
    return chromatogram(index, getBinaryData ? DetailLevel_FullData : DetailLevel_FullMetadata);
}

PWIZ_API_DECL ChromatogramPtr ChromatogramList_Thermo::chromatogram(size_t index, DetailLevel detailLevel) const
{
    boost::call_once(indexInitialized_.flag, boost::bind(&ChromatogramList_Thermo::createIndex, this));
    if (index>size())
        throw runtime_error(("[ChromatogramList_Thermo::chromatogram()] Bad index: "
                            + lexical_cast<string>(index)).c_str());

    const IndexEntry& ci = index_[index];
    ChromatogramPtr result(new Chromatogram);
    result->index = ci.index;
    result->id = ci.id;
    result->set(ci.chromatogramType);
    if (ci.polarityType != CVID_Unknown)
        result->set(ci.polarityType);

    bool getBinaryData = detailLevel == DetailLevel_FullData;

    try
    {
        rawfile_->setCurrentController(ci.controllerType, ci.controllerNumber);

        switch (ci.chromatogramType)
        {
            default:
                break;

            case MS_TIC_chromatogram:
            {
                if (detailLevel < DetailLevel_FullMetadata)
                    return result;

                CVID intensityUnits = ci.controllerType == Controller_MS ? MS_number_of_detector_counts : UO_picoampere;
                ChromatogramDataPtr cd = rawfile_->getChromatogramData(Type_TIC, ci.filter, 0, 0, 0, rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData)
                {
                    result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, intensityUnits);

                    if (ci.controllerType == Controller_MS)
                    {
                        auto msLevelArray = boost::make_shared<IntegerDataArray>();
                        result->integerDataArrayPtrs.emplace_back(msLevelArray);
                        msLevelArray->set(MS_non_standard_data_array, "ms level", UO_dimensionless_unit);
                        msLevelArray->data.resize(cd->times().size());
                        for (size_t i = 0; i < cd->times().size(); ++i)
                            msLevelArray->data[i] = rawfile_->getMSOrder(rawfile_->scanNumber(cd->times()[i]));
                    }

                    if (intensityUnits == UO_picoampere)
                    {
                        // Thermo seems to store CAD intensities as attoAmps but shows them as picoAmps in QualBrowser;
                        boost::range::for_each(result->getIntensityArray()->data, [&](auto& v) {v *= 1e-6;});
                    }
                }
                else result->defaultArrayLength = cd->size();
            }
            break;

            case MS_SIC_chromatogram: // generate SIC for <precursor>
            {
                if (detailLevel < DetailLevel_FullMetadata)
                    return result;

                ChromatogramDataPtr cd = rawfile_->getChromatogramData(Type_MassRange, index_[index].filter, 0, 100000, 0, rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData) result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, MS_number_of_detector_counts);
                else result->defaultArrayLength = cd->size();
            }
            break;

            /*case 3: // generate SRM TIC for <precursor>
            {
                vector<string> tokens;
                bal::split(tokens, ci.id, bal::is_any_of(" "));
                ChromatogramDataPtr cd = rawfile_->getChromatogramData(
                    Type_TIC, Operator_None, Type_MassRange,
                    "ms2 " + tokens[2], "", "", 0,
                    0, rawfile_->rt(rawfile_->value(NumSpectra)),
                    Smoothing_None, 0);
                pwiz::msdata::TimeIntensityPair* data = reinterpret_cast<pwiz::msdata::TimeIntensityPair*>(cd->data());
                if (getBinaryData) result->setTimeIntensityPairs(data, cd->size(), UO_minute, MS_number_of_detector_counts);
                else result->defaultArrayLength = cd->size();
            }
            break;*/

            case MS_SRM_chromatogram:
            {
                result->precursor.isolationWindow.set(MS_isolation_window_target_m_z, ci.q1, MS_m_z);
                ScanInfoPtr scanInfo = rawfile_->getScanInfoFromFilterString(ci.filter);
                ActivationType activationType = scanInfo->activationType();
                if (activationType == ActivationType_Unknown)
                    activationType = ActivationType_CID; // assume CID
                string polarity = polarityStringForFilter(ci.polarityType);

                bool hasSupplemental = scanInfo->supplementalActivationType() == ActivationType_ETD;

                setActivationType(activationType, hasSupplemental ? scanInfo->supplementalActivationType() : ActivationType_Unknown, result->precursor.activation);
                if (activationType == ActivationType_CID)
                    result->precursor.activation.set(MS_collision_energy, scanInfo->precursorActivationEnergy(0));
                if (hasSupplemental && !(scanInfo->supplementalActivationEnergy() > 0))
                    result->precursor.activation.set(MS_supplemental_collision_energy, scanInfo->supplementalActivationEnergy());

                result->product.isolationWindow.set(MS_isolation_window_target_m_z, ci.q3, MS_m_z);
                result->product.isolationWindow.set(MS_isolation_window_lower_offset, ci.q3Offset, MS_m_z);
                result->product.isolationWindow.set(MS_isolation_window_upper_offset, ci.q3Offset, MS_m_z);

                if (detailLevel < DetailLevel_FullMetadata)
                    return result;

                string q1 = (format("%.10g", std::locale::classic()) % ci.q1).str();
                string q3Range = (format("%.10g-%.10g", std::locale::classic())
                                  % (ci.q3 - ci.q3Offset)
                                  % (ci.q3 + ci.q3Offset)
                                 ).str();

                ChromatogramDataPtr cd = rawfile_->getChromatogramData(Type_MassRange,
                    polarity + "SRM ms2 " + q1 + " [" + q3Range + "]", ci.q3 - ci.q3Offset, ci.q3 + ci.q3Offset, 0,
                    rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData) result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, MS_number_of_detector_counts);
                else result->defaultArrayLength = cd->size();
            }
            break;

            case MS_SIM_chromatogram:
            {
                result->precursor.isolationWindow.set(MS_isolation_window_target_m_z, ci.q1, MS_m_z);
                result->precursor.isolationWindow.set(MS_isolation_window_lower_offset, ci.q3Offset, MS_m_z);
                result->precursor.isolationWindow.set(MS_isolation_window_upper_offset, ci.q3Offset, MS_m_z);

                if (detailLevel < DetailLevel_FullMetadata)
                    return result;

                string q1Range = (format("%.10g-%.10g", std::locale::classic())
                                  % (ci.q1 - ci.q3Offset)
                                  % (ci.q1 + ci.q3Offset)
                                 ).str();

                ChromatogramDataPtr cd = rawfile_->getChromatogramData(Type_MassRange,
                    "SIM ms [" + q1Range + "]", ci.q1 - ci.q3Offset, ci.q1 + ci.q3Offset, 0,
                    rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData) result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, MS_number_of_detector_counts);
                else result->defaultArrayLength = cd->size();
            }
            break;

            case MS_absorption_chromatogram: // PDA: generate "Total Scan" chromatogram for entire run
            {
                ChromatogramDataPtr cd = rawfile_->getChromatogramData(
                    Type_TotalScan, "", 0, 0, 0,
                    rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData) result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, UO_absorbance_unit);
                else result->defaultArrayLength = cd->size();
            }
            break;

            case MS_emission_chromatogram: // UV: generate "ECD" chromatogram for entire run
            {
                ChromatogramDataPtr cd = rawfile_->getChromatogramData(
                    Type_ECD, "", 0, 0, 0,
                    rawfile_->getFirstScanTime(), rawfile_->getLastScanTime());
                if (getBinaryData) result->setTimeIntensityArrays(cd->times(), cd->intensities(), UO_minute, UO_absorbance_unit);
                else result->defaultArrayLength = cd->size();
            }
            break;
        }

        return result;
    }
    catch (exception& e)
    {
        throw runtime_error("[ChromatogramList_Thermo::chromatogram()] Error retrieving chromatogram \"" + result->id + "\": " + e.what());
    }
    catch (...)
    {
        throw runtime_error("[ChromatogramList_Thermo::chromatogram()] Unknown exception retrieving chromatogram \"" + result->id + "\"");
    }
}

PWIZ_API_DECL ChromatogramList_Thermo::IndexEntry& ChromatogramList_Thermo::addChromatogram(const string& id, ControllerType controllerType, int controllerNumber, CVID chromatogramType, const string& filter) const
{
    index_.push_back(IndexEntry());
    IndexEntry& ci = index_.back();
    ci.controllerType = controllerType;
    ci.controllerNumber = controllerNumber;
    ci.filter = filter;
    ci.index = index_.size() - 1;
    ci.id = id;
    ci.chromatogramType = chromatogramType;
    ci.polarityType = CVID_Unknown;
    idMap_[ci.id] = ci.index;
    return ci;
}

PWIZ_API_DECL void ChromatogramList_Thermo::createIndex() const
{
    for (int controllerType = Controller_MS;
         controllerType < Controller_Count;
         ++controllerType)
    {
        long numControllers = rawfile_->getNumberOfControllersOfType((ControllerType) controllerType);
        for (long n=1; n <= numControllers; ++n)
        {
            try
            {
                rawfile_->setCurrentController((ControllerType)controllerType, n);
            }
            catch (exception& e)
            {
                // TODO: add warn_once for chromatograms
                cerr << "[ChromatogramList_Thermo::createIndex] error setting controller to " << ControllerTypeStrings[controllerType] << ": " << e.what() << endl;
                continue;
            }

            // skip this controller if it has no spectra
            if (rawfile_->getLastScanNumber() == 0)
                continue;

            switch ((ControllerType) controllerType)
            {
                case Controller_MS:
                {
                    // support file-level TIC for all file types
                    string globalFilter = config_.globalChromatogramsAreMs1Only ? "Full ms" : "";
                    addChromatogram("TIC", (ControllerType) controllerType, n, MS_TIC_chromatogram, globalFilter);

                    // for certain filter types, support additional chromatograms
                    vector<string> filterArray = rawfile_->getFilters();
                    ScanInfoPtr scanInfo = filterArray.empty() ? ScanInfoPtr() : rawfile_->getScanInfoFromFilterString(filterArray[0]);
                    for (size_t i=0, ic=filterArray.size(); i < ic; ++i)
                    {
                        string filterString = filterArray[i];
                        scanInfo->reinitialize(filterString);

                        switch (scanInfo->scanType())
                        {
                            case ScanType_SRM:
                            {
                                // produce spectra rather than a chromatogram
                                if (config_.srmAsSpectra)
                                    break;

                                string precursorMZ = (format("%.10g", std::locale::classic()) % scanInfo->precursorMZ(0)).str();
                                /*index_.push_back(IndexEntry());
                                IndexEntry& ci = index_.back();
                                ci.controllerType = (ControllerType) controllerType;
                                ci.controllerNumber = n;
                                ci.filter = filterString;
                                ci.index = index_.size()-1;
                                ci.id = "SRM TIC " + precursorMZ;
                                ci.q1 = filterParser.precursorMZs_[0];
                                idMap_[ci.id] = ci.index;*/

                                for (size_t j=0, jc=scanInfo->scanRangeCount(); j < jc; ++j)
                                {
                                    double q1 = scanInfo->precursorMZ(0);
                                    double q3 = (scanInfo->scanRange(j).first + scanInfo->scanRange(j).second) / 2.0;
                                    auto polarityType = translate(scanInfo->polarityType());
                                    string polarity = polarityStringForFilter(polarityType);
                                    string id = (format("%sSRM SIC %s,%.10g", std::locale::classic())
                                             % polarity
                                             % precursorMZ
                                             % q3
                                            ).str();
                                    IndexEntry& ci = addChromatogram(id, (ControllerType)controllerType, n, MS_SRM_chromatogram, filterString);
                                    ci.q1 = q1;
                                    ci.q3 = q3;
                                    ci.polarityType = polarityType;
                                    ci.q3Offset = (scanInfo->scanRange(j).second - scanInfo->scanRange(j).first) / 2.0;
                                }
                            }
                            break; // case ScanType_SRM

                            case ScanType_SIM:
                            {
                                // produce spectra rather than a chromatogram
                                if (config_.simAsSpectra)
                                    break;

                                for (size_t j=0, jc=scanInfo->scanRangeCount(); j < jc; ++j)
                                {
                                    double q1 = (scanInfo->scanRange(j).first + scanInfo->scanRange(j).second) / 2.0;
                                    auto polarityType = translate(scanInfo->polarityType());
                                    string polarity = polarityStringForFilter(polarityType);
                                    string id = (format("%sSIM SIC %.10g", std::locale::classic())
                                             % polarity
                                             % q1
                                            ).str();
                                    IndexEntry& ci = addChromatogram(id, (ControllerType)controllerType, n, MS_SIM_chromatogram, filterString);
                                    ci.q1 = q1;
                                    ci.polarityType = polarityType;

                                    // this should be q1Offset
                                    ci.q3Offset = (scanInfo->scanRange(j).second - scanInfo->scanRange(j).first) / 2.0;
                                }
                            }
                            break; // case ScanType_SIM

                            default:
                            case ScanType_Full:
                            /*{
                                string precursorMZ = lexical_cast<string>(filterParser.precursorMZs_[0]);
                                index_.push_back(make_pair(ChromatogramIdentity(), filterString));
                                ChromatogramIdentity& ci = index_.back().first;
                                ci.index = index_.size()-1;
                                ci.id = "SIC " + precursorMZ;
                                idMap_[ci.id] = ci.index;
                            }*/
                            break;
                        }
                    }
                }
                break; // case Controller_MS

                case Controller_PDA:
                {
                    addChromatogram("PDA " + lexical_cast<string>(n), (ControllerType)controllerType, n, MS_absorption_chromatogram, "");
                }
                break; // case Controller_PDA

                case Controller_UV:
                {
                    auto instrumentData = rawfile_->getInstrumentData();
                    if (bal::ends_with(instrumentData.Units, "AbsorbanceUnits") && (instrumentData.AxisLabelY.empty() || bal::starts_with(instrumentData.AxisLabelY, "UV")))
                    {
                        addChromatogram("UV " + lexical_cast<string>(n), (ControllerType)controllerType, n, MS_emission_chromatogram, "");
                    }
                    else if (bal::ends_with(instrumentData.AxisLabelY, "pA")) // picoamperes?
                    {
                        addChromatogram("CAD " + lexical_cast<string>(n), (ControllerType)controllerType, n, MS_TIC_chromatogram, "");
                    }
                    else
                    {
                        // TODO: pressure/flow chromatogram
                    }
                }
                break; // case Controller_UV

                default:
                    // TODO: are there sensible default chromatograms for other controller types?
                    break;
            }
        }
    }

    /*ostringstream imStream;
    std::auto_ptr<LabelValueArray> imArray = rawfile_->getInstrumentMethods();
    for(size_t i=0, end=imArray->size(); i < end; ++i)
        imStream << imArray->label(i) << imArray->value(i) << endl;
    string im = imStream.str();
    //  Parent   Center    Width   Time   CE   Q1PW   Q3PW   TubeLens
    boost::regex scanEventRegex("^\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+$");*/
}

PWIZ_API_DECL ChromatogramPtr ChromatogramList_Thermo::xic(double startTime, double endTime, const boost::icl::interval_set<double>& massRanges, int msLevel)
{
    /*string msLevelFilter("ms");
    if (msLevel > 1)
        msLevelFilter += lexical_cast<string>(msLevel);

    stringstream massRange;
    bool first = true;
    BOOST_FOREACH(const boost::icl::interval_set<double>::interval_type& range, massRanges)
    {
        if (!first)
        {
            first = false;
            massRange << ",";
        }
        massRange << range.lower() << "-" << range.upper();
    }

    ChromatogramDataPtr cd = rawfile_->getChromatogramData(msLevelFilter,
                                                           massRange.str(), "",
                                                           0,
                                                           startTime, endTime,
                                                           Smoothing_None, 0);
    pwiz::msdata::TimeIntensityPair* data = reinterpret_cast<pwiz::msdata::TimeIntensityPair*>(cd->data());*/

    ChromatogramPtr result(new Chromatogram);
    //result->id = (boost::format("XIC %1% %2% [%3%-%4%]") % msLevelFilter % massRange.str() % startTime % endTime).str();
    //result->setTimeIntensityPairs(data, cd->size(), UO_minute, MS_number_of_detector_counts);
    return result;
}

} // detail
} // msdata
} // pwiz

#else // PWIZ_READER_THERMO

//
// non-MSVC implementation
//

namespace pwiz {
namespace msdata {
namespace detail {

namespace {const ChromatogramIdentity emptyIdentity;}

size_t ChromatogramList_Thermo::size() const {return 0;}
const ChromatogramIdentity& ChromatogramList_Thermo::chromatogramIdentity(size_t index) const {return emptyIdentity;}
size_t ChromatogramList_Thermo::find(const string& id) const {return 0;}
ChromatogramPtr ChromatogramList_Thermo::chromatogram(size_t index, bool getBinaryData) const {return ChromatogramPtr();}
ChromatogramPtr ChromatogramList_Thermo::chromatogram(size_t index, DetailLevel detailLevel) const {return ChromatogramPtr();}

} // detail
} // msdata
} // pwiz

#endif // PWIZ_READER_THERMO

max_stars_repo_name: vagisha/pwiz

max_issues_repo_name: vagisha/pwiz

max_forks_repo_name: vagisha/pwiz


text:
/*
==============================================================================
KratosULFApplication
A library based on:
Kratos
A General Purpose Software for Multi-Physics Finite Element Analysis
Version 1.0 (Released on march 05, 2007).

Copyright 2007
Pooyan Dadvand, Riccardo Rossi, Pawel Ryzhakov
pooyan@cimne.upc.edu
rrossi@cimne.upc.edu
- CIMNE (International Center for Numerical Methods in Engineering),
Gran Capita' s/n, 08034 Barcelona, Spain

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 condition:

Distribution of this code for  any  commercial purpose  is permissible
ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNERS.

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.

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

//
//   Project Name:        Kratos
//   Last modified by:    $Author: anonymous $
//   Date:                $Date: 2008-10-23 12:50:01 $
//   Revision:            $Revision: 1.6 $
//
//

// System includes

#if defined(KRATOS_PYTHON)
// External includes
#include <boost/python.hpp>

// Project includes
#include "includes/define.h"
#include "ULF_application.h"
#include "custom_python/add_custom_io_to_python.h"
#include "custom_python/add_custom_strategies_to_python.h"
#include "custom_python/add_custom_utilities_to_python.h"
#include "custom_python/add_processes_to_python.h"

namespace Kratos
{

namespace Python
{

  using namespace boost::python;

  BOOST_PYTHON_MODULE(KratosULFApplication)
  {

	  class_<KratosULFApplication,
			  KratosULFApplication::Pointer,
			  bases<KratosApplication>, boost::noncopyable >("KratosULFApplication")
			;
		AddCustomUtilitiesToPython();
		AddCustomIOToPython();
		AddCustomStrategiesToPython();
		AddProcessesToPython();

		//registering variables in python
/*		KRATOS_REGISTER_IN_PYTHON_VARIABLE(NODAL_AREA)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(NODAL_H)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(IS_STRUCTURE)
		KRATOS_REGISTER_VKRATOS_REGISTER_IN_PYTHON_VARIABLEARIABLE(IS_FLUID)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(IS_BOUNDARY)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(IS_FREE_SURFACE)
*/
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(IS_LAGRANGIAN_INLET)

		KRATOS_REGISTER_IN_PYTHON_VARIABLE(PRESSURE_FORCE)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(FRACT_VEL)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(VAUX)

  }

}  // namespace Python.

}  // namespace Kratos.

#endif // KRATOS_PYTHON defined


text:
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "pxr/usd/usd/collectionAPI.h"
#include "pxr/usd/usd/schemaRegistry.h"
#include "pxr/usd/usd/typed.h"
#include "pxr/usd/usd/tokens.h"

#include "pxr/usd/sdf/types.h"
#include "pxr/usd/sdf/assetPath.h"

PXR_NAMESPACE_OPEN_SCOPE

// Register the schema with the TfType system.
TF_REGISTRY_FUNCTION(TfType)
{
    TfType::Define<UsdCollectionAPI,
        TfType::Bases< UsdAPISchemaBase > >();

}

TF_DEFINE_PRIVATE_TOKENS(
    _schemaTokens,
    (CollectionAPI)
    (collection)
);

/* virtual */
UsdCollectionAPI::~UsdCollectionAPI()
{
}

/* static */
UsdCollectionAPI
UsdCollectionAPI::Get(const UsdStagePtr &stage, const SdfPath &path)
{
    if (!stage) {
        TF_CODING_ERROR("Invalid stage");
        return UsdCollectionAPI();
    }
    TfToken name;
    if (!IsCollectionAPIPath(path, &name)) {
        TF_CODING_ERROR("Invalid collection path <%s>.", path.GetText());
        return UsdCollectionAPI();
    }
    return UsdCollectionAPI(stage->GetPrimAtPath(path.GetPrimPath()), name);
}

UsdCollectionAPI
UsdCollectionAPI::Get(const UsdPrim &prim, const TfToken &name)
{
    return UsdCollectionAPI(prim, name);
}

/* static */
bool
UsdCollectionAPI::IsSchemaPropertyBaseName(const TfToken &baseName)
{
    static TfTokenVector attrsAndRels = {
        UsdTokens->expansionRule,
        UsdTokens->includeRoot,
        UsdTokens->includes,
        UsdTokens->excludes,
    };

    return find(attrsAndRels.begin(), attrsAndRels.end(), baseName)
            != attrsAndRels.end();
}

/* static */
bool
UsdCollectionAPI::IsCollectionAPIPath(
    const SdfPath &path, TfToken *name)
{
    if (!path.IsPropertyPath()) {
        return false;
    }

    std::string propertyName = path.GetName();
    TfTokenVector tokens = SdfPath::TokenizeIdentifierAsTokens(propertyName);

    // The baseName of the  path can't be one of the
    // schema properties. We should validate this in the creation (or apply)
    // API.
    TfToken baseName = *tokens.rbegin();
    if (IsSchemaPropertyBaseName(baseName)) {
        return false;
    }

    if (tokens.size() >= 2
        && tokens[0] == _schemaTokens->collection) {
        *name = TfToken(propertyName.substr(
            _schemaTokens->collection.GetString().size() + 1));
        return true;
    }

    return false;
}

/* virtual */
UsdSchemaKind UsdCollectionAPI::_GetSchemaKind() const
{
    return UsdCollectionAPI::schemaKind;
}

/* static */
bool
UsdCollectionAPI::CanApply(
    const UsdPrim &prim, const TfToken &name, std::string *whyNot)
{
    return prim.CanApplyAPI<UsdCollectionAPI>(name, whyNot);
}

/* static */
UsdCollectionAPI
UsdCollectionAPI::Apply(const UsdPrim &prim, const TfToken &name)
{
    if (prim.ApplyAPI<UsdCollectionAPI>(name)) {
        return UsdCollectionAPI(prim, name);
    }
    return UsdCollectionAPI();
}

/* static */
const TfType &
UsdCollectionAPI::_GetStaticTfType()
{
    static TfType tfType = TfType::Find<UsdCollectionAPI>();
    return tfType;
}

/* static */
bool
UsdCollectionAPI::_IsTypedSchema()
{
    static bool isTyped = _GetStaticTfType().IsA<UsdTyped>();
    return isTyped;
}

/* virtual */
const TfType &
UsdCollectionAPI::_GetTfType() const
{
    return _GetStaticTfType();
}

/// Returns the property name prefixed with the correct namespace prefix, which
/// is composed of the the API's propertyNamespacePrefix metadata and the
/// instance name of the API.
static inline
TfToken
_GetNamespacedPropertyName(const TfToken instanceName, const TfToken propName)
{
    TfTokenVector identifiers =
        {_schemaTokens->collection, instanceName, propName};
    return TfToken(SdfPath::JoinIdentifier(identifiers));
}

UsdAttribute
UsdCollectionAPI::GetExpansionRuleAttr() const
{
    return GetPrim().GetAttribute(
        _GetNamespacedPropertyName(
            GetName(),
            UsdTokens->expansionRule));
}

UsdAttribute
UsdCollectionAPI::CreateExpansionRuleAttr(VtValue const &defaultValue, bool writeSparsely) const
{
    return UsdSchemaBase::_CreateAttr(
                       _GetNamespacedPropertyName(
                            GetName(),
                           UsdTokens->expansionRule),
                       SdfValueTypeNames->Token,
                       /* custom = */ false,
                       SdfVariabilityUniform,
                       defaultValue,
                       writeSparsely);
}

UsdAttribute
UsdCollectionAPI::GetIncludeRootAttr() const
{
    return GetPrim().GetAttribute(
        _GetNamespacedPropertyName(
            GetName(),
            UsdTokens->includeRoot));
}

UsdAttribute
UsdCollectionAPI::CreateIncludeRootAttr(VtValue const &defaultValue, bool writeSparsely) const
{
    return UsdSchemaBase::_CreateAttr(
                       _GetNamespacedPropertyName(
                            GetName(),
                           UsdTokens->includeRoot),
                       SdfValueTypeNames->Bool,
                       /* custom = */ false,
                       SdfVariabilityUniform,
                       defaultValue,
                       writeSparsely);
}

UsdRelationship
UsdCollectionAPI::GetIncludesRel() const
{
    return GetPrim().GetRelationship(
        _GetNamespacedPropertyName(
            GetName(),
            UsdTokens->includes));
}

UsdRelationship
UsdCollectionAPI::CreateIncludesRel() const
{
    return GetPrim().CreateRelationship(
                       _GetNamespacedPropertyName(
                           GetName(),
                           UsdTokens->includes),
                       /* custom = */ false);
}

UsdRelationship
UsdCollectionAPI::GetExcludesRel() const
{
    return GetPrim().GetRelationship(
        _GetNamespacedPropertyName(
            GetName(),
            UsdTokens->excludes));
}

UsdRelationship
UsdCollectionAPI::CreateExcludesRel() const
{
    return GetPrim().CreateRelationship(
                       _GetNamespacedPropertyName(
                           GetName(),
                           UsdTokens->excludes),
                       /* custom = */ false);
}

namespace {
static inline TfTokenVector
_ConcatenateAttributeNames(
    const TfToken instanceName,
    const TfTokenVector& left,
    const TfTokenVector& right)
{
    TfTokenVector result;
    result.reserve(left.size() + right.size());
    result.insert(result.end(), left.begin(), left.end());

    for (const TfToken attrName : right) {
        result.push_back(
            _GetNamespacedPropertyName(instanceName, attrName));
    }
    result.insert(result.end(), right.begin(), right.end());
    return result;
}
}

/*static*/
const TfTokenVector&
UsdCollectionAPI::GetSchemaAttributeNames(
    bool includeInherited, const TfToken instanceName)
{
    static TfTokenVector localNames = {
        UsdTokens->expansionRule,
        UsdTokens->includeRoot,
    };
    static TfTokenVector allNames =
        _ConcatenateAttributeNames(
            instanceName,
            UsdAPISchemaBase::GetSchemaAttributeNames(true),
            localNames);

    if (includeInherited)
        return allNames;
    else
        return localNames;
}

PXR_NAMESPACE_CLOSE_SCOPE

// ===================================================================== //
// Feel free to add custom code below this line. It will be preserved by
// the code generator.
//
// Just remember to wrap code in the appropriate delimiters:
// 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
// ===================================================================== //
// --(BEGIN CUSTOM CODE)--

#include "pxr/usd/usd/primRange.h"

#include <boost/functional/hash.hpp>

#include <set>

PXR_NAMESPACE_OPEN_SCOPE

using PathExpansionRuleMap = UsdCollectionMembershipQuery::PathExpansionRuleMap;

/* static */
UsdCollectionAPI
UsdCollectionAPI::GetCollection(const UsdStagePtr &stage,
                                const SdfPath &collectionPath)
{
    TfToken collectionName;
    if (!IsCollectionAPIPath(collectionPath, &collectionName)) {
        TF_CODING_ERROR("Invalid collection path <%s>.",
                        collectionPath.GetText());
        return UsdCollectionAPI();
    }

    return UsdCollectionAPI(stage->GetPrimAtPath(collectionPath.GetPrimPath()),
                            collectionName);
}

/* static */
UsdCollectionAPI
UsdCollectionAPI::GetCollection(const UsdPrim &prim,
                                const TfToken &name)
{
   return UsdCollectionAPI(prim, name);
}

SdfPath
UsdCollectionAPI::GetCollectionPath() const
{
    return GetPath().AppendProperty(_GetCollectionPropertyName());
}

/* static */
SdfPath
UsdCollectionAPI::GetNamedCollectionPath(
    const UsdPrim &prim,
    const TfToken &collectionName)
{
    return prim.GetPath().AppendProperty(TfToken(SdfPath::JoinIdentifier(
            UsdTokens->collection, collectionName)));
}

// XXX: This functionality should probably be exposed in the base-class for use
// in other API schemas.UsdPrim::HasAPI has similar code as well.
static std::vector<std::string>
_GetCollectionAPIAliases(const TfType &collSchemaType)
{
    // The alias for UsdCollectionAPI is already available as a static token
    // in _schemaTokes.
    std::vector<std::string> collectionAPIAliases{_schemaTokens->CollectionAPI};

    // If there are derived types of the CollectionAPI, include their aliases
    // too.
    std::set<TfType> derivedTypes;
    collSchemaType.GetAllDerivedTypes(&derivedTypes);
    if (!derivedTypes.empty()) {
        collectionAPIAliases.reserve(collectionAPIAliases.size() +
                                     derivedTypes.size());
        const auto schemaBaseType = TfType::Find<UsdSchemaBase>();
        for (const auto& derived : derivedTypes) {
            for (const auto &derivedAlias : schemaBaseType.GetAliases(derived)){
                collectionAPIAliases.push_back(derivedAlias);
            }
        }
    }

    return collectionAPIAliases;
}

/* static */
std::vector<UsdCollectionAPI>
UsdCollectionAPI::GetAllCollections(const UsdPrim &prim)
{
    std::vector<UsdCollectionAPI> collections;

    auto appliedSchemas = prim.GetAppliedSchemas();
    if (appliedSchemas.empty()) {
        return collections;
    }

    static const std::vector<std::string> collectionAPIAliases =
        _GetCollectionAPIAliases(_GetStaticTfType());

    for (const auto &appliedSchema : appliedSchemas) {
        for (const std::string &alias : collectionAPIAliases) {
            const std::string collAPIPrefix = alias +
                    UsdObject::GetNamespaceDelimiter();
            if (TfStringStartsWith(appliedSchema, collAPIPrefix)) {
                const std::string collectionName =
                        appliedSchema.GetString().substr(collAPIPrefix.size());
                collections.emplace_back(prim, TfToken(collectionName));
            }
        }
    }

    return collections;
}

TfToken
UsdCollectionAPI::_GetCollectionPropertyName(
    const TfToken &baseName /* =TfToken() */) const
{
    return TfToken(UsdTokens->collection.GetString() + ":" +
                   GetName().GetString() +
                   (baseName.IsEmpty() ? "" : (":" + baseName.GetString())));
}

bool
UsdCollectionAPI::IncludePath(const SdfPath &pathToInclude) const
{
    // If the prim is already included in the collection, do nothing.
    UsdCollectionMembershipQuery query  = ComputeMembershipQuery();
    if (query.IsPathIncluded(pathToInclude)) {
        return true;
    }

    if (pathToInclude == SdfPath::AbsoluteRootPath()) {
        CreateIncludeRootAttr(VtValue(true));
        return true;
    }

    // Check if the prim is directly excluded from the collection.
    SdfPathVector excludes;
    if (UsdRelationship excludesRel = GetExcludesRel()) {
        excludesRel.GetTargets(&excludes);

        if (std::find(excludes.begin(), excludes.end(), pathToInclude) !=
                excludes.end()) {
            excludesRel.RemoveTarget(pathToInclude);
            // Update the query object we have by updating the map and
            // reconstructing the query
            PathExpansionRuleMap map = query.GetAsPathExpansionRuleMap();
            auto it = map.find(pathToInclude);
            if (TF_VERIFY(it != map.end())) {
                map.erase(it);
                query = UsdCollectionMembershipQuery(
                    std::move(map), query.GetIncludedCollections());
            }
        }
    }

    // Now that we've removed the explicit excludes if there was one,
    // we can add the prim if it's not already included in the collection.
    if (!query.IsPathIncluded(pathToInclude)) {
        return CreateIncludesRel().AddTarget(pathToInclude);
    }

    return true;
}

bool
UsdCollectionAPI::ExcludePath(const SdfPath &pathToExclude) const
{
    // If the path is already excluded from a non-empty collection
    // (or simply not included at all), do nothing.
    UsdCollectionMembershipQuery query = ComputeMembershipQuery();
    if (!query.GetAsPathExpansionRuleMap().empty() &&
        !query.IsPathIncluded(pathToExclude)) {
        return true;
    }

    if (pathToExclude == SdfPath::AbsoluteRootPath()) {
        CreateIncludeRootAttr(VtValue(false));
        return true;
    }

    // Check if the path is directly included in the collection.
    SdfPathVector includes;
    if (UsdRelationship includesRel = GetIncludesRel()) {
        includesRel.GetTargets(&includes);

        if (std::find(includes.begin(), includes.end(), pathToExclude) !=
                includes.end()) {
            includesRel.RemoveTarget(pathToExclude);
            // Update the query object we have, instead of having to
            // recompute it.
            PathExpansionRuleMap map = query.GetAsPathExpansionRuleMap();
            auto it = map.find(pathToExclude);
            if (TF_VERIFY(it != map.end())) {
                map.erase(it);
                query = UsdCollectionMembershipQuery(
                    std::move(map), query.GetIncludedCollections());
            }
        }
    }

    // Now that we've removed the explicit include if there was one,
    // we can add an explicit exclude, if required.
    if (query.GetAsPathExpansionRuleMap().empty() ||
        query.IsPathIncluded(pathToExclude)) {
        return CreateExcludesRel().AddTarget(pathToExclude);
    }

    return true;
}

bool
UsdCollectionAPI::HasNoIncludedPaths() const
{
    SdfPathVector includes;
    GetIncludesRel().GetTargets(&includes);
    bool includeRoot = false;
    GetIncludeRootAttr().Get(&includeRoot);
    return includes.empty() && !includeRoot;
}

UsdCollectionMembershipQuery
UsdCollectionAPI::ComputeMembershipQuery() const
{
    UsdCollectionMembershipQuery query;
    ComputeMembershipQuery(&query);
    return query;
}

void
UsdCollectionAPI::ComputeMembershipQuery(
    UsdCollectionMembershipQuery *query) const
{
    if (!query) {
        TF_CODING_ERROR("Invalid query pointer.");
        return;
    }

    SdfPathSet chainedCollectionPaths { GetCollectionPath() };
    _ComputeMembershipQueryImpl(query, chainedCollectionPaths);
}

void
UsdCollectionAPI::_ComputeMembershipQueryImpl(
    UsdCollectionMembershipQuery *query,
    const SdfPathSet &chainedCollectionPaths,
    bool *foundCircularDependency) const
{
    if (!TF_VERIFY(query)) {
        return;
    }

    // Get the map from the query
    PathExpansionRuleMap map = query->GetAsPathExpansionRuleMap();
    SdfPathSet collections = query->GetIncludedCollections();

    // Get this collection's expansionRule.
    TfToken expRule;
    GetExpansionRuleAttr().Get(&expRule);

    if (expRule.IsEmpty()) {
        expRule = UsdTokens->expandPrims;
    }

    SdfPathVector includes, excludes;
    GetIncludesRel().GetTargets(&includes);
    GetExcludesRel().GetTargets(&excludes);

    // Consult includeRoot and include </> if requested.
    // (The separate attribute is necessary since </> cannot be a
    // target path in a relationship.)
    bool includeRoot = false;
    GetIncludeRootAttr().Get(&includeRoot);
    if (includeRoot) {
        includes.push_back(SdfPath::AbsoluteRootPath());
    }

    UsdStageWeakPtr stage = GetPrim().GetStage();

    for (const SdfPath &includedPath : includes) {
        TfToken collectionName;
        // Check if the included path is a collection. If it is, then
        // handle it specially.
        if (IsCollectionAPIPath(includedPath, &collectionName)) {
            if (chainedCollectionPaths.count(includedPath) > 0) {
                if (foundCircularDependency) {
                    *foundCircularDependency = true;
                } else {
                    // Issue a warning message if the clients of this method
                    // don't care about knowing if there's a circular
                    // dependency.
                    std::string includedCollectionsStr;
                    for (const SdfPath &collPath : chainedCollectionPaths) {
                        includedCollectionsStr.append(collPath.GetString());
                        includedCollectionsStr.append(", ");
                    }
                    TF_WARN("Found circular dependency involving the following "
                        "collections: [%s]", includedCollectionsStr.c_str());
                }
                // Continuing here avoids infinite recursion.
                continue;
            }

            SdfPath includedPrimPath = includedPath.GetPrimPath();
            UsdPrim includedPrim = stage->GetPrimAtPath(includedPrimPath);

            // The included collection must belong to a valid prim.
            // XXX: Should we check validity? We should skip circular
            // dependency check if we do validate.
            if (!includedPrim) {
                TF_WARN("Could not get prim at path <%s>, therefore cannot "
                    "include its collection '%s' in collection '%s'.",
                    includedPrimPath.GetText(), collectionName.GetText(),
                    GetName().GetText());
                continue;
            }

            UsdCollectionAPI includedCollection(includedPrim, collectionName);

            // Recursively compute the included collection's membership map with
            // an updated set of seen/included collection paths.
            //
            // Create a copy so we can add this collection to the list
            // before calling ComputeMembershipQuery.
            SdfPathSet seenCollectionPaths = chainedCollectionPaths;
            seenCollectionPaths.insert(includedPath);
            UsdCollectionMembershipQuery includedQuery;
            includedCollection._ComputeMembershipQueryImpl(&includedQuery,
                    seenCollectionPaths, foundCircularDependency);

            const PathExpansionRuleMap& includedMap =
                includedQuery.GetAsPathExpansionRuleMap();

            // Merge path expansion rule maps
            // We can't just do an insert here as we need to overwrite existing
            // entries with new values of expansion rule from other map
            for (const auto &pathAndExpansionRule : includedMap) {
                map[pathAndExpansionRule.first] = pathAndExpansionRule.second;
            }

            // Merge included collections
            collections.insert(includedPath);

            const SdfPathSet& includedCollections =
                includedQuery.GetIncludedCollections();
            collections.insert(
                includedCollections.begin(), includedCollections.end());

        } else {
            // Append included path
            map[includedPath] = expRule;
        }
    }

    // Process the excludes after the includes.
    for (const auto &p: excludes) {
        // Append excluded path
        map[p] = UsdTokens->exclude;
    }

    *query = UsdCollectionMembershipQuery(
        std::move(map), std::move(collections));
}

/* static */
std::set<UsdObject>
UsdCollectionAPI::ComputeIncludedObjects(
    const UsdCollectionMembershipQuery &query,
    const UsdStageWeakPtr &stage,
    const Usd_PrimFlagsPredicate &pred)
{
    return UsdComputeIncludedObjectsFromCollection(query, stage, pred);
}

/* static */
SdfPathSet
UsdCollectionAPI::ComputeIncludedPaths(
    const UsdCollectionMembershipQuery &query,
    const UsdStageWeakPtr &stage,
    const Usd_PrimFlagsPredicate &pred)
{
    return UsdComputeIncludedPathsFromCollection(query, stage, pred);
}

static bool
_AllRootmostRulesPassFilter(
    UsdCollectionMembershipQuery::PathExpansionRuleMap const& ruleMap,
    std::function<bool(std::pair<SdfPath, TfToken> const&)> const& filter)
{
    if (ruleMap.empty()) {
        return false;
    }
    for (const auto &rule: ruleMap) {
        // Check if this is a rootmost path (in other words, not
        // contained under another rule).
        bool isRootmost = true;
        for (SdfPath p = rule.first.GetParentPath();
             p != SdfPath::EmptyPath(); p = p.GetParentPath()) {
            if (ruleMap.find(p) != ruleMap.end()) {
                isRootmost = false;
                break;
            }
        }
        if (isRootmost && !filter(rule)) {
            return false;
        }
    }
    return true;
}

bool
UsdCollectionAPI::Validate(std::string *reason) const
{
    TfToken expansionRule;
    if (UsdAttribute expRuleAttr = GetExpansionRuleAttr()) {
        expRuleAttr.Get(&expansionRule);
    }

    // Validate value of expansionRule.
    if (!expansionRule.IsEmpty() &&
        expansionRule != UsdTokens->explicitOnly &&
        expansionRule != UsdTokens->expandPrims &&
        expansionRule != UsdTokens->expandPrimsAndProperties) {

        if (reason) {
            *reason += TfStringPrintf("Invalid expansionRule value '%s'\n",
                                      expansionRule.GetText());
        }
        return false;
    }

    // Check for circular dependencies.
    bool foundCircularDependency = false;
    SdfPathSet chainedCollectionPaths{GetCollectionPath()};
    // We're not interested in the computed query object here.
    UsdCollectionMembershipQuery query;
    _ComputeMembershipQueryImpl(&query, chainedCollectionPaths,
                                &foundCircularDependency);
    if (foundCircularDependency) {
        if (reason) {
            *reason += "Found one or more circular dependencies amongst "
                "the set of included (directly and transitively) collections.";
        }
        return false;
    }

    // Prohibit using both includes and excludes in top-level rules,
    // since the intent is ambiguous.
    if (query.HasExcludes()) {
        bool allExcludes = _AllRootmostRulesPassFilter(
            query.GetAsPathExpansionRuleMap(),
            [](std::pair<SdfPath, TfToken> const& rule) -> bool {
                return rule.second == UsdTokens->exclude;
            });
        bool allIncludes = _AllRootmostRulesPassFilter(
            query.GetAsPathExpansionRuleMap(),
            [](std::pair<SdfPath, TfToken> const& rule) -> bool {
                return rule.second != UsdTokens->exclude;
            });
        if (!allExcludes && !allIncludes) {
            if (reason) {
                *reason += "Found both includes and excludes among the "
                    "root-most rules -- interpretation is ambiguous";
            }
            return false;
        }
    }

    return true;
}

bool
UsdCollectionAPI::ResetCollection() const
{
    bool success = true;
    if (UsdRelationship includesRel = GetIncludesRel()) {
        success = includesRel.ClearTargets(/* removeSpec */ true) && success;
    }
    if (UsdRelationship excludesRel = GetExcludesRel()) {
        success = excludesRel.ClearTargets(/* removeSpec */ true) && success;
    }
    return success;
}

bool
UsdCollectionAPI::BlockCollection() const
{
    bool success = true;
    if (UsdRelationship includesRel = GetIncludesRel()) {
        success = includesRel.SetTargets({}) && success;
    }
    if (UsdRelationship excludesRel = GetExcludesRel()) {
        success = excludesRel.SetTargets({}) && success;
    }
    return success;
}

/* static */
bool
UsdCollectionAPI::CanContainPropertyName(const TfToken &name)
{
    return TfStringStartsWith(name, UsdTokens->collection);
}

PXR_NAMESPACE_CLOSE_SCOPE


text:
/***************************************************************************
   Copyright 2015 Ufora Inc.

   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
****************************************************************************/
#pragma once

#include <boost/bind.hpp>
#include "PolymorphicSharedPtr.hpp"

namespace PolymorphicSharedPtrBinder {

template<class T>
class ExtractWeakPtrAndCall0 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)())
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)();
		}
};

template<class T, class A1>
class ExtractWeakPtrAndCall1 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1), A1 a1)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)(a1);
		}
};

template<class T, class A1, class A2>
class ExtractWeakPtrAndCall2 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2), A1 a1, A2 a2)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)(a1, a2);
		}
};

template<class T, class A1, class A2, class A3>
class ExtractWeakPtrAndCall3 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)(a1, a2, a3);
		}
};

template<class T, class A1, class A2, class A3, class A4>
class ExtractWeakPtrAndCall4 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)(a1, a2, a3, a4);
		}
};

template<class T, class A1, class A2, class A3, class A4, class A5>
class ExtractWeakPtrAndCall5 {
public:
	static void call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return;

		( (*ptr).*fun)(a1, a2, a3, a4, a5);
		}
};

template<class T>
boost::function1<void, PolymorphicSharedWeakPtr<T> >
memberFunctionToWeakPtrFunction(void (T::* in)())
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall0<T>::call,
		_1,
		in
		);
	}

template<class T, class A1>
boost::function2<void, PolymorphicSharedWeakPtr<T>, A1>
memberFunctionToWeakPtrFunction(void (T::* in)(A1))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall1<T, A1>::call,
		_1,
		in,
		_2
		);
	}

template<class T, class A1, class A2>
boost::function3<void, PolymorphicSharedWeakPtr<T>, A1, A2>
memberFunctionToWeakPtrFunction(void (T::* in)(A1, A2))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall2<T, A1, A2>::call,
		_1,
		in,
		_2,
		_3
		);
	}

template<class T, class A1, class A2, class A3>
boost::function4<void, PolymorphicSharedWeakPtr<T>, A1, A2, A3>
memberFunctionToWeakPtrFunction(void (T::* in)(A1, A2, A3))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall3<T, A1, A2, A3>::call,
		_1,
		in,
		_2,
		_3,
		_4
		);
	}

template<class T, class A1, class A2, class A3, class A4>
boost::function5<void, PolymorphicSharedWeakPtr<T>, A1, A2, A3, A4>
memberFunctionToWeakPtrFunction(void (T::* in)(A1, A2, A3, A4))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall4<T, A1, A2, A3, A4>::call,
		_1,
		in,
		_2,
		_3,
		_4,
		_5
		);
	}

template<class T, class A1, class A2, class A3, class A4, class A5>
boost::function6<void, PolymorphicSharedWeakPtr<T>, A1, A2, A3, A4, A5>
memberFunctionToWeakPtrFunction(void (T::* in)(A1, A2, A3, A4, A5))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCall5<T, A1, A2, A3, A4, A5>::call,
		_1,
		in,
		_2,
		_3,
		_4,
		_5,
		_6
		);
	}

template<class T>
class ExtractWeakPtrAndCallOrReturnFalse0 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)())
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)();

		return true;
		}
};

template<class T, class A1>
class ExtractWeakPtrAndCallOrReturnFalse1 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1), A1 a1)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)(a1);

		return true;
		}
};

template<class T, class A1, class A2>
class ExtractWeakPtrAndCallOrReturnFalse2 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2), A1 a1, A2 a2)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)(a1, a2);

		return true;
		}
};

template<class T, class A1, class A2, class A3>
class ExtractWeakPtrAndCallOrReturnFalse3 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3), A1 a1, A2 a2, A3 a3)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)(a1, a2, a3);

		return true;
		}
};

template<class T, class A1, class A2, class A3, class A4>
class ExtractWeakPtrAndCallOrReturnFalse4 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)(a1, a2, a3, a4);

		return true;
		}
};

template<class T, class A1, class A2, class A3, class A4, class A5>
class ExtractWeakPtrAndCallOrReturnFalse5 {
public:
	static bool call(PolymorphicSharedWeakPtr<T> weakPtr, void (T::* fun)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
		{
		PolymorphicSharedPtr<T> ptr = weakPtr.lock();
		if (!ptr)
			return false;

		( (*ptr).*fun)(a1, a2, a3, a4, a5);

		return true;
		}
};

template<class T>
boost::function1<bool, PolymorphicSharedWeakPtr<T> >
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)())
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse0<T>::call,
		_1,
		in
		);
	}

template<class T, class A1>
boost::function2<bool, PolymorphicSharedWeakPtr<T>, A1>
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)(A1))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse1<T, A1>::call,
		_1,
		in,
		_2
		);
	}

template<class T, class A1, class A2>
boost::function3<bool, PolymorphicSharedWeakPtr<T>, A1, A2>
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)(A1, A2))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse2<T, A1, A2>::call,
		_1,
		in,
		_2,
		_3
		);
	}

template<class T, class A1, class A2, class A3>
boost::function4<bool, PolymorphicSharedWeakPtr<T>, A1, A2, A3>
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)(A1, A2, A3))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse3<T, A1, A2, A3>::call,
		_1,
		in,
		_2,
		_3,
		_4
		);
	}

template<class T, class A1, class A2, class A3, class A4>
boost::function5<bool, PolymorphicSharedWeakPtr<T>, A1, A2, A3, A4>
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)(A1, A2, A3, A4))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse4<T, A1, A2, A3, A4>::call,
		_1,
		in,
		_2,
		_3,
		_4,
		_5
		);
	}

template<class T, class A1, class A2, class A3, class A4, class A5>
boost::function6<bool, PolymorphicSharedWeakPtr<T>, A1, A2, A3, A4, A5>
memberFunctionToWeakPtrFunctionOrReturnFalse(void (T::* in)(A1, A2, A3, A4, A5))
	{
	using namespace boost;

	return boost::bind(
		ExtractWeakPtrAndCallOrReturnFalse5<T, A1, A2, A3, A4, A5>::call,
		_1,
		in,
		_2,
		_3,
		_4,
		_5,
		_6
		);
	}

}

ext: hpp

max_stars_repo_name: ufora/ufora


text:
//------------------------------------------------------------------------------
/// \file Radix_tests.cpp
/// \author Ernest Yeung
/// \email  ernestyalumni@gmail.com
/// \ref https://en.wikipedia.org/wiki/Radix
/// https://www.youtube.com/watch?v=NLKQEOgBAnw
/// Algorithms: Bit Manipulation. HackerRank. Gayle Laakmann McDowell.
/// \details To run only the Bits unit tests, do this:
/// ./Check --run_test="Algorithms/Bits"
///
/// Also, consider running the BooleanAlgebra_tests, as such:
/// ./Check --run_test="Utilities/BooleanAlgebra_tests"
//------------------------------------------------------------------------------
#include "Algorithms/Bits/Masks.h"
#include "Algorithms/Bits/Shift.h"
#include "Cpp/Numerics/BitCast.h"
#include "Cpp/Utilities/SuperBitSet.h"
#include "Utilities/EndianConversions.h"
#include "Utilities/ToHexString.h"

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

using Algorithms::Bits::clear_bit;
using Algorithms::Bits::is_bit_set_high;
using Algorithms::Bits::set_bit_high;
using Algorithms::Bits::logical_right_shift;
using Cpp::Numerics::bit_cast;
using Cpp::Utilities::SuperBitSet;
using Cpp::Utilities::number_of_bits_in_a_byte;
using Utilities::ToHexString;
using Utilities::to_big_endian;
using Utilities::to_little_endian;

BOOST_AUTO_TEST_SUITE(Algorithms)
BOOST_AUTO_TEST_SUITE(Bits)
BOOST_AUTO_TEST_SUITE(NumericalRepresentation_tests)

// cf. https://www.cs.utexas.edu/users/fussell/courses/cs429h/lectures/Lecture_2-429h.pdf
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(BinaryRepresentation)
{
  // Limits
  {
    std::cout << "\n\n Unsigned limits \n";

    std::cout << "std::numeric_limits<uint8_t>::max(): " <<
      static_cast<unsigned int>(std::numeric_limits<uint8_t>::max()) << "\n";
        // 255
    std::cout << "std::numeric_limits<uint16_t>::max(): " <<
      std::numeric_limits<uint16_t>::max() << "\n"; // 65535
    std::cout << "std::numeric_limits<uint32_t>::max(): " <<
      std::numeric_limits<uint32_t>::max() << "\n"; // 4294967295
    std::cout << "std::numeric_limits<uint64_t>::max(): " <<
      std::numeric_limits<uint64_t>::max() << "\n"; // 18446744073709551615

    std::cout << "\n FloatingPoint limits \n";

    std::cout << "std::numeric_limits<float>::max(): " <<
      std::numeric_limits<float>::max() << "\n";
    std::cout << "std::numeric_limits<double>::max(): " <<
      std::numeric_limits<double>::max() << "\n";
  }

  {
    std::cout << "\n\n Signed limits \n";

    std::cout << "std::numeric_limits<int8_t>::max(): " <<
      static_cast<unsigned int>(std::numeric_limits<int8_t>::max()) << "\n";
        // 127
    std::cout << "std::numeric_limits<int16_t>::max(): " <<
      std::numeric_limits<int16_t>::max() << "\n"; // 32767
    std::cout << "std::numeric_limits<int32_t>::max(): " <<
      std::numeric_limits<int32_t>::max() << "\n"; // 2147483647
    std::cout << "std::numeric_limits<int64_t>::max(): " <<
      std::numeric_limits<int64_t>::max() << "\n"; // 18446744073709551615

    std::cout << "std::numeric_limits<int8_t>::min(): " <<
      static_cast<int>(std::numeric_limits<int8_t>::min()) << "\n";
        // -128
    std::cout << "std::numeric_limits<int16_t>::min(): " <<
      std::numeric_limits<int16_t>::min() << "\n"; // -32768
    std::cout << "std::numeric_limits<int32_t>::min(): " <<
      std::numeric_limits<int32_t>::min() << "\n"; // -2147483648
    std::cout << "std::numeric_limits<int64_t>::min(): " <<
      std::numeric_limits<int64_t>::min() << "\n"; // 18446744073709551615
  }

  // Examples
  {
    std::cout << "\n Examples of Binary Representations \n";

    {
      SuperBitSet<sizeof(uint16_t) * number_of_bits_in_a_byte> x {15213};
      std::cout << "15213_10 as binary: " << x.to_string() << "\n";
    }
  }

}

// cf. https://en.cppreference.com/w/cpp/language/integer_literal
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(IntegerLiteralBitsAsChars)
{
  {
    const uint8_t au {0b00};
    BOOST_TEST_REQUIRE(au == 0);

    SuperBitSet<8> bits8 {au};
    BOOST_TEST(bits8.to_string() == "00000000");

    const char ac {0b00};
    SuperBitSet<8> cbits8 {ac};
    BOOST_TEST(cbits8.to_string() == "00000000");
  }
  {
    const uint8_t au {0b01};
    BOOST_TEST_REQUIRE(au == 1);

    SuperBitSet<8> bits8 {au};
    BOOST_TEST(bits8.to_string() == "00000001");

    const char ac {0b01};
    SuperBitSet<8> cbits8 {ac};
    BOOST_TEST(cbits8.to_string() == "00000001");
  }
  {
    const uint8_t au {0b10};
    BOOST_TEST_REQUIRE(au == 2);

    SuperBitSet<8> bits8 {au};
    BOOST_TEST(bits8.to_string() == "00000010");

    const char ac {0b10};
    SuperBitSet<8> cbits8 {ac};
    BOOST_TEST(cbits8.to_string() == "00000010");
  }
  {
    const uint8_t au {0b11};
    BOOST_TEST_REQUIRE(au == 3);

    SuperBitSet<8> bits8 {au};
    BOOST_TEST(bits8.to_string() == "00000011");

    const char ac {0b11};
    SuperBitSet<8> cbits8 {ac};
    BOOST_TEST(cbits8.to_string() == "00000011");
  }
}

// cf. https://www.youtube.com/watch?v=NLKQEOgBAnw
// Algorithms: Bit Manipulation,  HackerRank with Gayle Laakmann McDowell.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(BinaryAdditionCarriesOne)
{
  const uint8_t a {0b0101};
  const uint8_t b {0b0011};
  const uint8_t c {a + b};
  SuperBitSet<8> c8 {c};
  BOOST_TEST(c8.to_string() == "00001000");
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(TwosComplement)
{
  // cf. https://www.cs.utexas.edu/users/fussell/courses/cs429h/lectures/Lecture_3-429h.pdf
  // "Encoding Integers."
  {
    const int16_t x {15213};
    const SuperBitSet<16> xbits16 {x};
    BOOST_TEST(xbits16.to_string() == "0011101101101101");
    ToHexString<int16_t> xh {x};

    // *** stack smashing detected ***: terminated
    // unknown location(0): fatal error: in "Algorithms/Bits/NumericalRepresentation_tests/TwosComplement": signal: SIGABRT (application abort requested)
    //BOOST_TEST(xh() == "6d3b");
    ToHexString<int16_t> be_xh {to_big_endian(xh)};
    //BOOST_TEST(be_xh() == "3b6d");

    const int16_t y {-15213};
    const auto yu = bit_cast<uint16_t>(y);
    const SuperBitSet<16> yubits16 {yu};
    BOOST_TEST(yubits16.to_string() == "1100010010010011");
    ToHexString<int16_t> yh {y};
    //BOOST_TEST(yh() == "93c4");
    ToHexString<int16_t> be_yh {to_big_endian(yh)};
    //BOOST_TEST(be_yh() == "c493");
  }

  {
    const int8_t a {18};
    const auto au = bit_cast<uint8_t>(a);
    SuperBitSet<8> aubits8 {au};
    // Sign bit is 0 for positive.
    BOOST_TEST(aubits8.to_string() == "00010010");
  }
  {
    const int8_t a {-18};
    const auto au = bit_cast<uint8_t>(a);
    SuperBitSet<8> aubits8 {au};
    // Sign bit is 0 for positive.
    BOOST_TEST(aubits8.to_string() == "11101110");
  }
}

// cf. http://sandbox.mc.edu/~bennet/cs110/tc/add.html
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(
  TwosComplementBinaryAdditionWhenSumIsNotArithemticallyCorrect)
{
  // Overflow, no carryout (at sign bit). Sum is not correct.
  {
    const int8_t x {104};
    const SuperBitSet<8> xbits8 {x};
    BOOST_TEST(xbits8.to_string() == "01101000");
    ToHexString<int8_t> xh {x};
    //BOOST_TEST(xh() == "68");

    const int8_t y {45};
    const SuperBitSet<8> ybits8 {y};
    BOOST_TEST(ybits8.to_string() == "00101101");
    ToHexString<int8_t> yh {y};
    //BOOST_TEST(yh() == "2d");

    const auto z = x + y;
    BOOST_TEST(sizeof(z) == 4);
    const SuperBitSet<8> zbits8 {z};
    BOOST_TEST(zbits8.to_string() == "10010101");
    BOOST_TEST(zbits8.to_ulong() == 149);

    // "Wraps around" to -128 and "up".
    const int8_t z8 {-107};
    const SuperBitSet<8> z8bits8 {bit_cast<uint8_t>(z8)};
    BOOST_TEST(z8bits8.to_string() == "10010101");
  }
  // Overflow, with incidental carryout. Sum is not correct.
  {
    const int8_t x {-103};
    const SuperBitSet<8> xbits8 {bit_cast<uint8_t>(x)};
    BOOST_TEST(xbits8.to_string() == "10011001");
    ToHexString<int8_t> xh {x};

    // *** stack smashing detected ***: terminated
    // unknown location(0): fatal error: in "Algorithms/Bits/NumericalRepresentation_tests/TwosComplementBinaryAdditionWhenSumIsNotArithemticallyCorrect": signal: SIGABRT (application abort requested)
    //BOOST_TEST(xh() == "99");

    const int8_t y {-69};
    const SuperBitSet<8> ybits8 {bit_cast<uint8_t>(y)};
    BOOST_TEST(ybits8.to_string() == "10111011");
    ToHexString<int8_t> yh {y};

    // *** stack smashing detected ***: terminated
    // unknown location(0): fatal error: in "Algorithms/Bits/NumericalRepresentation_tests/TwosComplementBinaryAdditionWhenSumIsNotArithemticallyCorrect": signal: SIGABRT (application abort requested)
    //BOOST_TEST(yh() == "bb");

    const auto z = x + y;
    BOOST_TEST(sizeof(z) == 4);
    const SuperBitSet<32> zbits32 {bit_cast<uint32_t>(z)};
    BOOST_TEST(zbits32.to_string() == "11111111111111111111111101010100");
    BOOST_TEST(z == -172);

    // "Wraps around" to -128 and "up".
    const int8_t z8 {84};
    const SuperBitSet<8> z8bits8 {bit_cast<uint8_t>(z8)};
    BOOST_TEST(z8bits8.to_string() == "01010100");
  }
}

// cf. https://www.youtube.com/watch?v=NLKQEOgBAnw
// Algorithms: Bit Manipulation,  HackerRank with Gayle Laakmann McDowell.
// This test breaks down step by step the algorithm Gayle described clearly that
// also explains the name two's complement to get the additive inverse (i.e.
// the negative) of a positive integer.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(GetAdditiveInverseFromComplement)
{
  const int8_t x {18};
  SuperBitSet<8> xbits8 {bit_cast<uint8_t>(x)};
  BOOST_TEST(xbits8.to_string() == "00010010");

  BOOST_TEST((~xbits8).to_string() == "11101101");

  const int8_t not_x {~x};
  SuperBitSet<8> not_xbits8 {bit_cast<uint8_t>(not_x)};
  BOOST_TEST(not_xbits8.to_string() == "11101101");

  const int8_t not_x_plus_1 {not_x + 1};
  SuperBitSet<8> not_x_plus_1bits8 {bit_cast<uint8_t>(not_x_plus_1)};
  BOOST_TEST(not_x_plus_1bits8.to_string() == "11101110");

  const int8_t y {-18};
  SuperBitSet<8> ybits8 {bit_cast<uint8_t>(y)};
  BOOST_TEST(ybits8.to_string() == "11101110");
  BOOST_TEST(ybits8.to_string() == not_x_plus_1bits8.to_string());
}

// cf. https://youtu.be/NLKQEOgBAnw?t=399
// Logical right shift fills in zero for sign bit.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(LogicalRightShiftOnNegativeNumbers)
{
  SuperBitSet<8> xbits8 {bit_cast<uint8_t>(logical_right_shift<int8_t>(23, 1))};
  BOOST_TEST(xbits8.to_string() == "00001011");

  int8_t y {-23};
  SuperBitSet<8> ybits8 {bit_cast<uint8_t>(y)};
  BOOST_TEST(ybits8.to_string() == "11101001");

  SuperBitSet<8> zbits8 {bit_cast<uint8_t>(logical_right_shift<int8_t>(y, 1))};
  BOOST_TEST(zbits8.to_string() == "01110100");
}

// cf. https://youtu.be/NLKQEOgBAnw?t=399
// Arithmetic right shift shifts everything to the right including sign bit,
// fills in sign bit with original sign bit.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ArithmeticRightShiftOnNegativeNumbers)
{
  int8_t x {-23};
  int8_t y {1};
  // Works, but it warns. Narrowing conversion.
  //int8_t z {x >> y};
  //SuperBitSet<8> xbits8 {bit_cast<uint8_t>(z)};
  //BOOST_TEST(xbits8.to_string() == "11110100");
  {
    int8_t x {-22};
    SuperBitSet<8> xbits8 {bit_cast<uint8_t>(x)};
    BOOST_TEST(xbits8.to_string() == "11101010");
    // Works but it warns. Narrowing conversion.
    //int8_t y {x >> 1};
    //SuperBitSet<8> ybits8 {bit_cast<uint8_t>(y)};
    //BOOST_TEST(ybits8.to_string() == "11110101");
  }
}

// cf. https://en.cppreference.com/w/cpp/language/operator_arithmetic
// lhs << rhs
// left shift of lhs by rhs bits.
// lhs >> rhs
// right shift of lhs by rhs bits
// For built-in operators, lhs and rhs must both have integral or unscoped
// enumeration type. Integral promotions performed on both operands.
// Return type is type of left operand after integral promotions.
// For unsigned a, value of a << b is value a * 2^b, reduced modulo 2^N, where
// N is number of bits in return type (that is, bitwise left shift is performed
// and bits that get shifted out of destination type are discarded).
// For negative a, behavior of a << b is undefined.
//
// since C++14
// For signed and non-negative a, if a*2^b representable in unsigned version
// of return type, then taht value, converted to signed, is value of a << b
// For negative a, value of a >> b is implementation-defined (in most
// implementations, this performs arithmetic right shift, so result remains
// negative)
//
// since C++20
// a << b is unique value congrent to a * 2^b modulo 2^N where N is number of
// bits in return type (that is bitwise left shift performed and bits that get
// shifted out of destination type are discarded).
// Value of a >> b is a/2^b, rounded down (i.e., right shift on signed a is
// arithmetic right shift).

BOOST_AUTO_TEST_SUITE(BitwiseShiftOperator_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(Examples)
{
  char c {0x10};
  SuperBitSet<8> cbits8 {bit_cast<uint8_t>(c)};
  BOOST_TEST(cbits8.to_string() == "00010000");

  SuperBitSet<32> xbits32 {bit_cast<uint32_t>(c << 10)};
  BOOST_TEST(
    xbits32.to_string() == "00000000000000000100000000000000");
  BOOST_TEST((c << 10) == 0x4000);

  unsigned long long ull {0x123};
  SuperBitSet<number_of_bits_in_a_byte * sizeof(unsigned long long)>
    ullbits_ull {bit_cast<uint64_t>(ull)};
  BOOST_TEST(
    ullbits_ull.to_string() ==
      "0000000000000000000000000000000000000000000000000000000100100011");

  {
    SuperBitSet<number_of_bits_in_a_byte * sizeof(unsigned long long)>
      xbits_ull {bit_cast<uint64_t>(ull << 1)};

    BOOST_TEST(
      xbits_ull.to_string() ==
        "0000000000000000000000000000000000000000000000000000001001000110");

    BOOST_TEST(xbits_ull.to_ullong() == 0x246);
  }
  {
    // overflow in unsigned
    SuperBitSet<number_of_bits_in_a_byte * sizeof(unsigned long long)>
      xbits_ull {bit_cast<uint64_t>(ull << 63)};

    BOOST_TEST(
      xbits_ull.to_string() ==
        "1000000000000000000000000000000000000000000000000000000000000000");

    BOOST_TEST(xbits_ull.to_ullong() == 0x8000000000000000);
  }

  // For negative a, value of a >> b in most implementations is arithmetic right
  // shift, shifts everything to right including sign bit, fills in sign bit
  // with original sign bit.
  long long ll {-1000};
  SuperBitSet<number_of_bits_in_a_byte * sizeof(long long)>
    llbits_ll {bit_cast<uint64_t>(ll)};
  BOOST_TEST(
    llbits_ll.to_string() ==
      "1111111111111111111111111111111111111111111111111111110000011000");

  SuperBitSet<number_of_bits_in_a_byte * sizeof(long long)>
    xbits_ll {bit_cast<uint64_t>(ll >> 1)};
  BOOST_TEST(
    xbits_ll.to_string() ==
      "1111111111111111111111111111111111111111111111111111111000001100");
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(BitwiseLeftShiftOfNegativeNumbers)
{
  int8_t x {-5};
  SuperBitSet<8> xbits8 {bit_cast<uint8_t>(x)};
  // Indeed this is the "two's complement" of 00000101 = 5; take the complement
  // and then add 1.
  BOOST_TEST(xbits8.to_string() == "11111011");

  // cf. https://en.cppreference.com/w/cpp/language/operator_arithmetic
  // cppreference says this is undefined.
  x << 1;

  auto y {x << 1};

  // std::cout << y << "\n"; // -10

  // template argument deduction/substitution failed.
  // SuperBitSet<8> ybits8 {bit_cast<uint8_t>(x << 1)};
  // SuperBitSet<8> ybits8 {bit_cast<int8_t>(x << 1)};
  //SuperBitSet<16> ybits16 {bit_cast<uint16_t>(x << 1)};
  //SuperBitSet<16> ybits16 {bit_cast<int16_t>(x << 1)};

  SuperBitSet<32> ybits32 {bit_cast<uint32_t>(y)};

  BOOST_TEST(ybits32.to_string() == "11111111111111111111111111110110");
}

BOOST_AUTO_TEST_SUITE_END() // BitwiseShiftOperator_tests

BOOST_AUTO_TEST_SUITE(Masks_tests)

// https://youtu.be/NLKQEOgBAnw?t=444
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(BitwiseAndToGetIthBit)
{
  int8_t x {44};

  SuperBitSet<8> xbits8 {bit_cast<uint8_t>(x)};
  BOOST_TEST(xbits8.to_string() == "00101100");

  // (x & (1 << c)) != 0
  BOOST_TEST((x & (1 << 5)) != 0);

  BOOST_TEST((x & (1 << 7)) == 0);
  BOOST_TEST((x & (1 << 6)) == 0);
  BOOST_TEST((x & (1 << 4)) == 0);
  BOOST_TEST((x & (1 << 1)) == 0);
  BOOST_TEST((x & (1 << 0)) == 0);

  BOOST_TEST((x & (1 << 3)) != 0);
  BOOST_TEST((x & (1 << 2)) != 0);

  BOOST_TEST(!is_bit_set_high(x, 0));
  BOOST_TEST(!is_bit_set_high(x, 1));
  BOOST_TEST(!is_bit_set_high(x, 4));
  BOOST_TEST(!is_bit_set_high(x, 6));
  BOOST_TEST(!is_bit_set_high(x, 7));

  BOOST_TEST(is_bit_set_high(x, 2));
  BOOST_TEST(is_bit_set_high(x, 3));
  BOOST_TEST(is_bit_set_high(x, 5));

  int8_t y {-44}; // 11010100

  BOOST_TEST(is_bit_set_high(y, 2));
  BOOST_TEST(is_bit_set_high(y, 4));
  BOOST_TEST(is_bit_set_high(y, 6));
  BOOST_TEST(is_bit_set_high(y, 7));

  BOOST_TEST(!is_bit_set_high(y, 0));
  BOOST_TEST(!is_bit_set_high(y, 1));
  BOOST_TEST(!is_bit_set_high(y, 3));
  BOOST_TEST(!is_bit_set_high(y, 5));
}

// https://youtu.be/NLKQEOgBAnw?t=466
// Set ith bit, x | (1 << i)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(BitwiseOrToSetIthBit)
{
  int8_t x {44};

  BOOST_TEST(is_bit_set_high(x, 5));
  x = set_bit_high(x, 5);
  BOOST_TEST(is_bit_set_high(x, 5));

  BOOST_TEST(!is_bit_set_high(x, 6));
  x = set_bit_high(x, 6);
  BOOST_TEST(is_bit_set_high(x, 6));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClearBitWithMaskWithAll1ButThatSpot)
{
  int8_t x {44};
  BOOST_TEST(is_bit_set_high(x, 5));
  x = clear_bit(x, 5);
  BOOST_TEST(!is_bit_set_high(x, 5));
}

BOOST_AUTO_TEST_SUITE_END() // Masks_tests

BOOST_AUTO_TEST_SUITE_END() // Radix_tests
BOOST_AUTO_TEST_SUITE_END() // Bits
BOOST_AUTO_TEST_SUITE_END() // Algorithms

max_stars_repo_name: ernestyalumni/HrdwCCppCUDA

max_issues_repo_name: ernestyalumni/HrdwCCppCUDA

max_forks_repo_name: ernestyalumni/HrdwCCppCUDA


text:
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga  2006-2008
//
// 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)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_entity_code
#include <boost/intrusive/list.hpp>

using namespace boost::intrusive;

//A class that can be inserted in an intrusive list
class entity : public list_base_hook<>
{
   public:
   virtual ~entity();
   //...
};

//"some_entity" derives from "entity"
class some_entity  :  public entity
{/**/};

//Definition of the intrusive list
typedef list<entity> entity_list;

//A global list
entity_list global_list;

//The destructor removes itself from the global list
entity::~entity()
{  global_list.erase(entity_list::s_iterator_to(*this));  }

//Function to insert a new "some_entity" in the global list
void insert_some_entity()
{  global_list.push_back (*new some_entity(/*...*/));  }

//Function to clear an entity from the intrusive global list
void clear_list ()
{
   // entity's destructor removes itself from the global list implicitly
   while (!global_list.empty())
      delete &global_list.front();
}

int main()
{
   //Insert some new entities
   insert_some_entity();
   insert_some_entity();
   //global_list's destructor will free objects
   return 0;
}

//]


text:
#pragma once

#ifdef ASIOCHAN_USE_STANDALONE_ASIO

#include <system_error>

#include <asio/any_io_executor.hpp>
#include <asio/async_result.hpp>
#include <asio/awaitable.hpp>
#include <asio/co_spawn.hpp>
#include <asio/detached.hpp>
#include <asio/dispatch.hpp>
#include <asio/execution/executor.hpp>
#include <asio/execution_context.hpp>
#include <asio/post.hpp>
#include <asio/strand.hpp>
#include <asio/this_coro.hpp>
#include <asio/use_awaitable.hpp>

#else

#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/execution/executor.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/this_coro.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/system/error_code.hpp>

#endif

namespace asiochan
{
#ifdef ASIOCHAN_USE_STANDALONE_ASIO
    namespace asio = ::asio;
    namespace system = ::std;
#else
    namespace asio = ::boost::asio;
    namespace system = ::boost::system;
#endif
}  // namespace asiochan


text:
#include <moja/flint/configuration/externalvariable.h>

#include <moja/test/mocktransformconfiguration.h>

#include <moja/dynamic.h>

#include <boost/test/unit_test.hpp>

using moja::DynamicObject;
using moja::flint::configuration::ExternalVariable;
using moja::test::MockTransformConfiguration;

BOOST_AUTO_TEST_SUITE(ExternalVariableConfigurationTests);

BOOST_AUTO_TEST_CASE(flint_configuration_ExternalVariable_ConstructorThrowsExceptionIfNameIsEmpty) {
   auto badNames = {"", "  "};
   for (auto name : badNames) {
      BOOST_CHECK_THROW(ExternalVariable(name, std::make_shared<MockTransformConfiguration>()), std::invalid_argument);
   }
}

BOOST_AUTO_TEST_CASE(flint_configuration_ExternalVariable_GetName) {
   auto name = "test";
   ExternalVariable variable(name, std::make_shared<MockTransformConfiguration>());
   BOOST_CHECK_EQUAL(name, variable.name());
}
BOOST_AUTO_TEST_SUITE_END();

max_stars_repo_name: moja-global/flint

max_issues_repo_name: moja-global/flint

max_forks_repo_name: moja-global/flint


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_IEEE_FUNCTIONS_NEGATENZ_HPP_INCLUDED
#define BOOST_SIMD_IEEE_FUNCTIONS_NEGATENZ_HPP_INCLUDED
#include <boost/simd/include/functor.hpp>
#include <boost/dispatch/include/functor.hpp>

namespace boost { namespace simd { namespace tag
  {
   /*!
     @brief negatenz generic tag

     Represents the negatenz function in generic contexts.

     @par Models:
        Hierarchy
   **/
    struct negatenz_ : ext::elementwise_<negatenz_>
    {
      /// @brief Parent hierarchy
      typedef ext::elementwise_<negatenz_> parent;
      template<class... Args>
      static BOOST_FORCEINLINE BOOST_AUTO_DECLTYPE dispatch(Args&&... args)
      BOOST_AUTO_DECLTYPE_BODY( dispatching_negatenz_( ext::adl_helper(), static_cast<Args&&>(args)... ) )
    };
  }
  namespace ext
  {
   template<class Site>
   BOOST_FORCEINLINE generic_dispatcher<tag::negatenz_, Site> dispatching_negatenz_(adl_helper, boost::dispatch::meta::unknown_<Site>, ...)
   {
     return generic_dispatcher<tag::negatenz_, Site>();
   }
   template<class... Args>
   struct impl_negatenz_;
  }
  /*!
    Returns a0 multiplied by the signnz of a1
    The result is unspecified if a1 is NaN

    @par Semantic:

    @code
    T r = negatenz(a0,a1);
    @endcode

    is similar to:

    @code
    T r = a0*signnz(a1)
    @endcode

    @param a0

    @param a1

    @return a value of same type as the inputs
  **/
  BOOST_DISPATCH_FUNCTION_IMPLEMENTATION(tag::negatenz_, negatenz, 2)
} }

#endif