<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDED_SC_SOURCE_UI_OPTDLG_CALCOPTIONSDLG_HXX
#define INCLUDED_SC_SOURCE_UI_OPTDLG_CALCOPTIONSDLG_HXX

#include <config_features.h>

#include <vcl/dialog.hxx>
#include <vcl/button.hxx>
#include <vcl/edit.hxx>
#include <vcl/field.hxx>
#include <vcl/fixed.hxx>
#include <vcl/layout.hxx>
#include <vcl/lstbox.hxx>

#include <svx/checklbx.hxx>

#include <svtools/treelistbox.hxx>

#include "calcconfig.hxx"

#if HAVE_FEATURE_OPENCL
#include <opencl/openclconfig.hxx>
#include <opencl/platforminfo.hxx>
#endif

class ScCalcOptionsDialog : public ModalDialog
{
public:
    ScCalcOptionsDialog(vcl::Window* pParent, const ScCalcConfig& rConfig);
    virtual ~ScCalcOptionsDialog();

    DECL_LINK( BtnAutomaticSelectHdl, void* );
    DECL_LINK( DeviceSelHdl, void* );
    DECL_LINK( NumModifiedHdl, void * );
    DECL_LINK( EditModifiedHdl, Edit * );
    DECL_LINK( TestClickHdl, PushButton* );
    DECL_LINK( AsZeroModifiedHdl, CheckBox*);
    DECL_LINK( ConversionModifiedHdl, ListBox*);
    DECL_LINK( SyntaxModifiedHdl, ListBox*);
    DECL_LINK( CBUseOpenCLHdl, CheckBox*);
    DECL_LINK( SpinOpenCLMinSizeHdl, NumericField*);

    const ScCalcConfig& GetConfig() const { return maConfig;}

private:
    void OpenCLAutomaticSelectionChanged();
    void SelectedDeviceChanged();
#if HAVE_FEATURE_OPENCL
    void fillOpenCLList();
#endif

    SvTreeListEntry *createItem(const OUString &rCaption, const OUString& sValue) const;
    void     setValueAt(size_t nPos, const OUString &rString);
#if HAVE_FEATURE_OPENCL
    OpenCLConfig::ImplMatcherSet& CurrentWhiteOrBlackList();
    const OpenCLConfig::ImplMatcher& CurrentWhiteOrBlackListEntry();
#endif

private:

    CheckBox*     mpEmptyAsZero;
    ListBox*      mpConversion;
    ListBox*      mpSyntax;
    CheckBox*     mpUseOpenCL;
    NumericField* mpSpinButton;
    VclMultiLineEdit* mpEditField;
    PushButton* mpTestButton;

    ListBox* mpLbOptionEdit;

    FixedText* mpFtAnnotation;
    FixedText* mpFtFrequency;
    FixedText* mpFtComputeUnits;
    FixedText* mpFtMemory;

    SvTreeListBox* mpOpenclInfoList;
    RadioButton* mpBtnAutomaticSelectionTrue;
    RadioButton* mpBtnAutomaticSelectionFalse;

    OUString maSoftware;

    ScCalcConfig maConfig;
#if HAVE_FEATURE_OPENCL
    std::vector<OpenCLPlatformInfo> maPlatformInfo;
#endif

    bool mbSelectedEmptyStringAsZero;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#1261766 Uninitialized pointer field<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDED_SC_SOURCE_UI_OPTDLG_CALCOPTIONSDLG_HXX
#define INCLUDED_SC_SOURCE_UI_OPTDLG_CALCOPTIONSDLG_HXX

#include <config_features.h>

#include <vcl/dialog.hxx>
#include <vcl/button.hxx>
#include <vcl/edit.hxx>
#include <vcl/field.hxx>
#include <vcl/fixed.hxx>
#include <vcl/layout.hxx>
#include <vcl/lstbox.hxx>

#include <svx/checklbx.hxx>

#include <svtools/treelistbox.hxx>

#include "calcconfig.hxx"

#if HAVE_FEATURE_OPENCL
#include <opencl/openclconfig.hxx>
#include <opencl/platforminfo.hxx>
#endif

class ScCalcOptionsDialog : public ModalDialog
{
public:
    ScCalcOptionsDialog(vcl::Window* pParent, const ScCalcConfig& rConfig);
    virtual ~ScCalcOptionsDialog();

    DECL_LINK( BtnAutomaticSelectHdl, void* );
    DECL_LINK( DeviceSelHdl, void* );
    DECL_LINK( NumModifiedHdl, void * );
    DECL_LINK( EditModifiedHdl, Edit * );
    DECL_LINK( TestClickHdl, PushButton* );
    DECL_LINK( AsZeroModifiedHdl, CheckBox*);
    DECL_LINK( ConversionModifiedHdl, ListBox*);
    DECL_LINK( SyntaxModifiedHdl, ListBox*);
    DECL_LINK( CBUseOpenCLHdl, CheckBox*);
    DECL_LINK( SpinOpenCLMinSizeHdl, NumericField*);

    const ScCalcConfig& GetConfig() const { return maConfig;}

private:
    void OpenCLAutomaticSelectionChanged();
    void SelectedDeviceChanged();
#if HAVE_FEATURE_OPENCL
    void fillOpenCLList();
#endif

    SvTreeListEntry *createItem(const OUString &rCaption, const OUString& sValue) const;
    void     setValueAt(size_t nPos, const OUString &rString);
#if HAVE_FEATURE_OPENCL
    OpenCLConfig::ImplMatcherSet& CurrentWhiteOrBlackList();
    const OpenCLConfig::ImplMatcher& CurrentWhiteOrBlackListEntry();
#endif

private:

    CheckBox*     mpEmptyAsZero;
    ListBox*      mpConversion;
    ListBox*      mpSyntax;
    CheckBox*     mpUseOpenCL;
    NumericField* mpSpinButton;
    VclMultiLineEdit* mpEditField;
    PushButton* mpTestButton;

    FixedText* mpFtFrequency;
    FixedText* mpFtComputeUnits;
    FixedText* mpFtMemory;

    SvTreeListBox* mpOpenclInfoList;
    RadioButton* mpBtnAutomaticSelectionTrue;
    RadioButton* mpBtnAutomaticSelectionFalse;

    OUString maSoftware;

    ScCalcConfig maConfig;
#if HAVE_FEATURE_OPENCL
    std::vector<OpenCLPlatformInfo> maPlatformInfo;
#endif

    bool mbSelectedEmptyStringAsZero;
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//
// Copyright 2016 Francisco Jerez
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

///
/// \file
/// Some thin wrappers around the Clang/LLVM API used to preserve
/// compatibility with older API versions while keeping the ifdef clutter low
/// in the rest of the clover::llvm subtree.  In case of an API break please
/// consider whether it's possible to preserve backwards compatibility by
/// introducing a new one-liner inline function or typedef here under the
/// compat namespace in order to keep the running code free from preprocessor
/// conditionals.
///

#ifndef CLOVER_LLVM_COMPAT_HPP
#define CLOVER_LLVM_COMPAT_HPP

#include "util/algorithm.hpp"

#include <llvm/Linker/Linker.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Target/TargetMachine.h>
#if HAVE_LLVM >= 0x0400
#include <llvm/Support/Error.h>
#else
#include <llvm/Support/ErrorOr.h>
#endif

#if HAVE_LLVM >= 0x0307
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Analysis/TargetLibraryInfo.h>
#else
#include <llvm/PassManager.h>
#include <llvm/Target/TargetLibraryInfo.h>
#include <llvm/Target/TargetSubtargetInfo.h>
#include <llvm/Support/FormattedStream.h>
#endif

#include <clang/Frontend/CodeGenOptions.h>
#include <clang/Frontend/CompilerInstance.h>

namespace clover {
   namespace llvm {
      namespace compat {
#if HAVE_LLVM >= 0x0307
         typedef ::llvm::TargetLibraryInfoImpl target_library_info;
#else
         typedef ::llvm::TargetLibraryInfo target_library_info;
#endif

#if HAVE_LLVM >= 0x0500
         const auto lang_as_offset = 0;
#else
         const auto lang_as_offset = clang::LangAS::Offset;
#endif

         inline void
         set_lang_defaults(clang::CompilerInvocation &inv,
                           clang::LangOptions &lopts, clang::InputKind ik,
                           const ::llvm::Triple &t,
                           clang::PreprocessorOptions &ppopts,
                           clang::LangStandard::Kind std) {
#if HAVE_LLVM >= 0x0309
            inv.setLangDefaults(lopts, ik, t, ppopts, std);
#else
            inv.setLangDefaults(lopts, ik, std);
#endif
         }

         inline void
         add_link_bitcode_file(clang::CodeGenOptions &opts,
                               const std::string &path) {
#if HAVE_LLVM >= 0x0500
            clang::CodeGenOptions::BitcodeFileToLink F;

            F.Filename = path;
            F.PropagateAttrs = true;
            F.LinkFlags = ::llvm::Linker::Flags::None;
            opts.LinkBitcodeFiles.emplace_back(F);
#elif HAVE_LLVM >= 0x0308
            opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
#else
            opts.LinkBitcodeFile = path;
#endif
         }

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::legacy::PassManager pass_manager;
#else
         typedef ::llvm::PassManager pass_manager;
#endif

         inline void
         add_data_layout_pass(pass_manager &pm) {
#if HAVE_LLVM < 0x0307
            pm.add(new ::llvm::DataLayoutPass());
#endif
         }

         inline void
         add_internalize_pass(pass_manager &pm,
                              const std::vector<std::string> &names) {
#if HAVE_LLVM >= 0x0309
            pm.add(::llvm::createInternalizePass(
                      [=](const ::llvm::GlobalValue &gv) {
                         return std::find(names.begin(), names.end(),
                                          gv.getName()) != names.end();
                      }));
#else
            pm.add(::llvm::createInternalizePass(std::vector<const char *>(
                      map(std::mem_fn(&std::string::data), names))));
#endif
         }

         inline std::unique_ptr<::llvm::Linker>
         create_linker(::llvm::Module &mod) {
#if HAVE_LLVM >= 0x0308
            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(mod));
#else
            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(&mod));
#endif
         }

         inline bool
         link_in_module(::llvm::Linker &linker,
                        std::unique_ptr<::llvm::Module> mod) {
#if HAVE_LLVM >= 0x0308
            return linker.linkInModule(std::move(mod));
#else
            return linker.linkInModule(mod.get());
#endif
         }

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file;
#else
         typedef ::llvm::formatted_raw_ostream raw_ostream_to_emit_file;
#endif

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::DataLayout data_layout;
#else
         typedef const ::llvm::DataLayout *data_layout;
#endif

         inline data_layout
         get_data_layout(::llvm::TargetMachine &tm) {
#if HAVE_LLVM >= 0x0307
            return tm.createDataLayout();
#else
            return tm.getSubtargetImpl()->getDataLayout();
#endif
         }

#if HAVE_LLVM >= 0x0309
         const auto default_reloc_model = ::llvm::None;
#else
         const auto default_reloc_model = ::llvm::Reloc::Default;
#endif

         template<typename M, typename F> void
         handle_module_error(M &mod, const F &f) {
#if HAVE_LLVM >= 0x0400
            if (::llvm::Error err = mod.takeError())
               ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) {
                     f(eib.message());
                  });
#else
            if (!mod)
               f(mod.getError().message());
#endif
         }
      }
   }
}

#endif
<commit_msg>clover: Add missing include to compat header<commit_after>//
// Copyright 2016 Francisco Jerez
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

///
/// \file
/// Some thin wrappers around the Clang/LLVM API used to preserve
/// compatibility with older API versions while keeping the ifdef clutter low
/// in the rest of the clover::llvm subtree.  In case of an API break please
/// consider whether it's possible to preserve backwards compatibility by
/// introducing a new one-liner inline function or typedef here under the
/// compat namespace in order to keep the running code free from preprocessor
/// conditionals.
///

#ifndef CLOVER_LLVM_COMPAT_HPP
#define CLOVER_LLVM_COMPAT_HPP

#include "util/algorithm.hpp"

#include <llvm/Linker/Linker.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Target/TargetMachine.h>
#if HAVE_LLVM >= 0x0400
#include <llvm/Support/Error.h>
#else
#include <llvm/Support/ErrorOr.h>
#endif

#if HAVE_LLVM >= 0x0307
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Analysis/TargetLibraryInfo.h>
#else
#include <llvm/PassManager.h>
#include <llvm/Target/TargetLibraryInfo.h>
#include <llvm/Target/TargetSubtargetInfo.h>
#include <llvm/Support/FormattedStream.h>
#endif

#include <clang/Basic/TargetInfo.h>
#include <clang/Frontend/CodeGenOptions.h>
#include <clang/Frontend/CompilerInstance.h>

namespace clover {
   namespace llvm {
      namespace compat {
#if HAVE_LLVM >= 0x0307
         typedef ::llvm::TargetLibraryInfoImpl target_library_info;
#else
         typedef ::llvm::TargetLibraryInfo target_library_info;
#endif

#if HAVE_LLVM >= 0x0500
         const auto lang_as_offset = 0;
#else
         const auto lang_as_offset = clang::LangAS::Offset;
#endif

         inline void
         set_lang_defaults(clang::CompilerInvocation &inv,
                           clang::LangOptions &lopts, clang::InputKind ik,
                           const ::llvm::Triple &t,
                           clang::PreprocessorOptions &ppopts,
                           clang::LangStandard::Kind std) {
#if HAVE_LLVM >= 0x0309
            inv.setLangDefaults(lopts, ik, t, ppopts, std);
#else
            inv.setLangDefaults(lopts, ik, std);
#endif
         }

         inline void
         add_link_bitcode_file(clang::CodeGenOptions &opts,
                               const std::string &path) {
#if HAVE_LLVM >= 0x0500
            clang::CodeGenOptions::BitcodeFileToLink F;

            F.Filename = path;
            F.PropagateAttrs = true;
            F.LinkFlags = ::llvm::Linker::Flags::None;
            opts.LinkBitcodeFiles.emplace_back(F);
#elif HAVE_LLVM >= 0x0308
            opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
#else
            opts.LinkBitcodeFile = path;
#endif
         }

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::legacy::PassManager pass_manager;
#else
         typedef ::llvm::PassManager pass_manager;
#endif

         inline void
         add_data_layout_pass(pass_manager &pm) {
#if HAVE_LLVM < 0x0307
            pm.add(new ::llvm::DataLayoutPass());
#endif
         }

         inline void
         add_internalize_pass(pass_manager &pm,
                              const std::vector<std::string> &names) {
#if HAVE_LLVM >= 0x0309
            pm.add(::llvm::createInternalizePass(
                      [=](const ::llvm::GlobalValue &gv) {
                         return std::find(names.begin(), names.end(),
                                          gv.getName()) != names.end();
                      }));
#else
            pm.add(::llvm::createInternalizePass(std::vector<const char *>(
                      map(std::mem_fn(&std::string::data), names))));
#endif
         }

         inline std::unique_ptr<::llvm::Linker>
         create_linker(::llvm::Module &mod) {
#if HAVE_LLVM >= 0x0308
            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(mod));
#else
            return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(&mod));
#endif
         }

         inline bool
         link_in_module(::llvm::Linker &linker,
                        std::unique_ptr<::llvm::Module> mod) {
#if HAVE_LLVM >= 0x0308
            return linker.linkInModule(std::move(mod));
#else
            return linker.linkInModule(mod.get());
#endif
         }

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file;
#else
         typedef ::llvm::formatted_raw_ostream raw_ostream_to_emit_file;
#endif

#if HAVE_LLVM >= 0x0307
         typedef ::llvm::DataLayout data_layout;
#else
         typedef const ::llvm::DataLayout *data_layout;
#endif

         inline data_layout
         get_data_layout(::llvm::TargetMachine &tm) {
#if HAVE_LLVM >= 0x0307
            return tm.createDataLayout();
#else
            return tm.getSubtargetImpl()->getDataLayout();
#endif
         }

#if HAVE_LLVM >= 0x0309
         const auto default_reloc_model = ::llvm::None;
#else
         const auto default_reloc_model = ::llvm::Reloc::Default;
#endif

         template<typename M, typename F> void
         handle_module_error(M &mod, const F &f) {
#if HAVE_LLVM >= 0x0400
            if (::llvm::Error err = mod.takeError())
               ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) {
                     f(eib.message());
                  });
#else
            if (!mod)
               f(mod.getError().message());
#endif
         }
      }
   }
}

#endif
<|endoftext|>


<commit_before>#include "App.h"

#include "../examples/helpers/AsyncFileReader.h"
#include "../examples/helpers/AsyncFileStreamer.h"

int main(int argc, char **argv) {

    AsyncFileStreamer *asyncFileStreamer = new AsyncFileStreamer("/home/alexhultman/v0.15/public");

    uWS::/*SSL*/App(/*{
        .key_file_name = "/home/alexhultman/uWebSockets/misc/ssl/key.pem",
        .cert_file_name = "/home/alexhultman/uWebSockets/misc/ssl/cert.pem",
        .dh_params_file_name = "/home/alexhultman/dhparams.pem",
        .passphrase = "1234"
    }*/)/*.get("/*", [](auto *res, auto *req) {

        res->end("GET /WILDCARD");

    })*/.get("/:param1/:param2", [](auto *res, auto *req) {

        res->write("GET /:param1/:param2 = ");
        res->write(req->getParameter(0));
        res->write(" and ");
        res->end(req->getParameter(1));

    }).post("/hello", [asyncFileStreamer](auto *res, auto *req) {

        // depending on the file type we want to also add mime!
        //asyncFileStreamer->streamFile(res, req->getUrl());

        res->end("POST /hello");

    }).get("/hello", [](auto *res, auto *req) {

        res->end("GET /hello");

    }).unhandled([](auto *res, auto *req) {

        res->end("Here's nothing for you to see!");

    }).listen(3000, [](auto *token) {
        if (token) {
            std::cout << "Listening on port " << 3000 << std::endl;
        }
    }).run();

}
<commit_msg>Write some formatted content on unhandled<commit_after>#include "App.h"

#include "../examples/helpers/AsyncFileReader.h"
#include "../examples/helpers/AsyncFileStreamer.h"

int main(int argc, char **argv) {

    AsyncFileStreamer *asyncFileStreamer = new AsyncFileStreamer("/home/alexhultman/v0.15/public");

    uWS::/*SSL*/App(/*{
        .key_file_name = "/home/alexhultman/uWebSockets/misc/ssl/key.pem",
        .cert_file_name = "/home/alexhultman/uWebSockets/misc/ssl/cert.pem",
        .dh_params_file_name = "/home/alexhultman/dhparams.pem",
        .passphrase = "1234"
    }*/)/*.get("/*", [](auto *res, auto *req) {

        res->end("GET /WILDCARD");

    })*/.get("/:param1/:param2", [](auto *res, auto *req) {

        res->write("GET /:param1/:param2 = ");
        res->write(req->getParameter(0));
        res->write(" and ");
        res->end(req->getParameter(1));

    }).post("/hello", [asyncFileStreamer](auto *res, auto *req) {

        // depending on the file type we want to also add mime!
        //asyncFileStreamer->streamFile(res, req->getUrl());

        res->end("POST /hello");

    }).get("/hello", [](auto *res, auto *req) {

        res->end("GET /hello");

    }).unhandled([](auto *res, auto *req) {

        res->writeStatus("404 Not Found");
        res->writeHeader("Content-Type", "text/html; charset=utf-8");
        res->end("
404 Not Found
µWebSockets v0.15");

    }).listen(3000, [](auto *token) {
        if (token) {
            std::cout << "Listening on port " << 3000 << std::endl;
        }
    }).run();

}
<|endoftext|>


<commit_before>/*
    Binary search
    -------------
    A searching algorithm that finds the index of a target value within a
    sorted array using divide and conquer.

    Time complexity
    ---------------
    O(log(N)), where N is the number of elements in the array.

    Space complexity
    ----------------
    O(1).
*/

#include <vector>

/*
    binary_search
    -------------
    It compares the target value to the middle element of the array; if they
    are unequal, the half in which the target cannot lie is eliminated and the
    search continues on the remaining half until it is successful. If the search
    ends with the remaining half being empty, the target is not in the array.
*/

template <typename T>
int binary_search(const T& value, const std::vector<T>& sorted_values,
        const int low, const int high) {
    int mid = low + (high - low) / 2;

    if (value == sorted_values[mid])
        return mid;
    else if (low <= high) {
        if (value < sorted_values[mid]) {
            // value must be between indices low and mid-1, if exists
            return binary_search(value, sorted_values, low, mid - 1);
        }
        else if (value > sorted_values[mid]) {
            // value must be between indices mid+1 and high, if exists
            return binary_search(value, sorted_values, mid + 1, high);
        }
    }

    return -1;
}

/*
    binary_search
    -------------
    Convenience function for binary search that requires minimal arguments.
*/

template <typename T>
int binary_search(const T& value, const std::vector<T>& sorted_values) {
    return binary_search(value, sorted_values, 0, sorted_values.size() - 1);
}
<commit_msg>Handle case when vector is empty<commit_after>/*
    Binary search
    -------------
    A searching algorithm that finds the index of a target value within a
    sorted array using divide and conquer.

    Time complexity
    ---------------
    O(log(N)), where N is the number of elements in the array.

    Space complexity
    ----------------
    O(1).
*/

#include <vector>

/*
    binary_search
    -------------
    It compares the target value to the middle element of the array; if they
    are unequal, the half in which the target cannot lie is eliminated and the
    search continues on the remaining half until it is successful. If the search
    ends with the remaining half being empty, the target is not in the array.
*/

template <typename T>
int binary_search(const T& value, const std::vector<T>& sorted_values,
        const int low, const int high) {
    int mid = low + (high - low) / 2;

    if (value == sorted_values[mid])
        return mid;
    else if (low <= high) {
        if (value < sorted_values[mid]) {
            // value must be between indices low and mid-1, if exists
            return binary_search(value, sorted_values, low, mid - 1);
        }
        else if (value > sorted_values[mid]) {
            // value must be between indices mid+1 and high, if exists
            return binary_search(value, sorted_values, mid + 1, high);
        }
    }

    return -1;
}

/*
    binary_search
    -------------
    Convenience function for binary search that requires minimal arguments.
*/

template <typename T>
int binary_search(const T& value, const std::vector<T>& sorted_values) {
    if (sorted_values.size() == 0)
        return -1;

    return binary_search(value, sorted_values, 0, sorted_values.size() - 1);
}
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2008 - 2010 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *    Stefan Marr, Vrije Universiteit Brussel - Initial Implementation
 ******************************************************************************/

# include <gtest/gtest.h>

# include "headers.h"

/**
 * It is supposed to be filled with NULL on initialization.
 */
TEST(Preheader, DomainHeaderSize) {
  // Basic assumption first
  ASSERT_EQ(sizeof(oop_int_t), sizeof(u_oop_int_t));

  // Domain header needs to fit into this header word
  ASSERT_EQ(sizeof(u_oop_int_t), sizeof(domain_info_t));
}

TEST(Preheader, Initialization) {
  struct Preheader h;

  h.initialize_preheader();

  ASSERT_EQ(1, Int_Tag);

# if Extra_Preheader_Word_Experiment
  ASSERT_EQ(Int_Tag, h.sly_ensemble_collection_pointer);
# endif

  ASSERT_EQ(Int_Tag, h.domain.raw_value);
  ASSERT_TRUE(h.domain.bits.int_tag);

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());
}

TEST(Preheader, DomainHeaderLayout) {
  /* Verifying some basic assumptions about the bit layout */

  struct Preheader h;
  h.initialize_preheader();

  h.domain.raw_value = 0xFFFFFFFF;

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());

  ASSERT_EQ(0xFFFFFFFF, h.domain_info().raw_value);
  ASSERT_EQ(0x01FFFFFF, h.domain_info().bits.logic_id);  // That is the max value for the logic id

  ASSERT_TRUE(h.domain_info().bits.foreign_sync_read);
  ASSERT_TRUE(h.domain_info().bits.foreign_sync_write);
  ASSERT_TRUE(h.domain_info().bits.foreign_sync_execute);

  ASSERT_TRUE(h.domain_info().bits.foreign_async_read);
  ASSERT_TRUE(h.domain_info().bits.foreign_async_write);
  ASSERT_TRUE(h.domain_info().bits.foreign_async_execute);

  // Now clear the bits and verify the resulting raw_value
  h.domain.bits.foreign_sync_read    = false;
  h.domain.bits.foreign_sync_write   = false;
  h.domain.bits.foreign_sync_execute = false;

  h.domain.bits.foreign_async_read    = false;
  h.domain.bits.foreign_async_write   = false;
  h.domain.bits.foreign_async_execute = false;

  ASSERT_EQ(0x3FFFFFF, h.domain_header().raw_value);   // This basically says, that the policy flags are the highest (most significant)
  ASSERT_EQ(0x1FFFFFF, h.domain_header().bits.logic_id);

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());
}
<commit_msg>Old tests are not compiled, but might still be needed later<commit_after>/******************************************************************************
 *  Copyright (c) 2008 - 2010 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *    Stefan Marr, Vrije Universiteit Brussel - Initial Implementation
 ******************************************************************************/

# include <gtest/gtest.h>

# include "headers.h"

# ifdef domain_info_t

/**
 * It is supposed to be filled with NULL on initialization.
 */
TEST(Preheader, DomainHeaderSize) {
  // Basic assumption first
  ASSERT_EQ(sizeof(oop_int_t), sizeof(u_oop_int_t));

  // Domain header needs to fit into this header word
  ASSERT_EQ(sizeof(u_oop_int_t), sizeof(domain_info_t));
}

TEST(Preheader, Initialization) {
  struct Preheader h;

  h.initialize_preheader();

  ASSERT_EQ(1, Int_Tag);

# if Extra_Preheader_Word_Experiment
  ASSERT_EQ(Int_Tag, h.sly_ensemble_collection_pointer);
# endif

  ASSERT_EQ(Int_Tag, h.domain.raw_value);
  ASSERT_TRUE(h.domain.bits.int_tag);

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());
}

TEST(Preheader, DomainHeaderLayout) {
  /* Verifying some basic assumptions about the bit layout */

  struct Preheader h;
  h.initialize_preheader();

  h.domain.raw_value = 0xFFFFFFFF;

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());

  ASSERT_EQ(0xFFFFFFFF, h.domain_info().raw_value);
  ASSERT_EQ(0x01FFFFFF, h.domain_info().bits.logic_id);  // That is the max value for the logic id

  ASSERT_TRUE(h.domain_info().bits.foreign_sync_read);
  ASSERT_TRUE(h.domain_info().bits.foreign_sync_write);
  ASSERT_TRUE(h.domain_info().bits.foreign_sync_execute);

  ASSERT_TRUE(h.domain_info().bits.foreign_async_read);
  ASSERT_TRUE(h.domain_info().bits.foreign_async_write);
  ASSERT_TRUE(h.domain_info().bits.foreign_async_execute);

  // Now clear the bits and verify the resulting raw_value
  h.domain.bits.foreign_sync_read    = false;
  h.domain.bits.foreign_sync_write   = false;
  h.domain.bits.foreign_sync_execute = false;

  h.domain.bits.foreign_async_read    = false;
  h.domain.bits.foreign_async_write   = false;
  h.domain.bits.foreign_async_execute = false;

  ASSERT_EQ(0x3FFFFFF, h.domain_header().raw_value);   // This basically says, that the policy flags are the highest (most significant)
  ASSERT_EQ(0x1FFFFFF, h.domain_header().bits.logic_id);

  ASSERT_TRUE(Oop::from_bits(h.domain.raw_value).is_int());
}

# endif
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2014 Igor Zinken - http://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "baseaudioevent.h"
#include "../global.h"
#include "../utilities/utils.h"

// constructor / destructor

BaseAudioEvent::BaseAudioEvent()
{
    _buffer            = 0;
    _enabled           = true;
    _destroyableBuffer = true;
    _loopeable         = false;
    _locked            = false;
}

BaseAudioEvent::~BaseAudioEvent()
{
    // DebugTool::log( "BaseAudioEvent::destructor" );
    destroy();
}

/* public methods */

int BaseAudioEvent::getSampleLength()
{
    return _sampleLength;
}

void BaseAudioEvent::setSampleLength( int value )
{
    _sampleLength = value;
}

int BaseAudioEvent::getSampleStart()
{
    return _sampleStart;
}

void BaseAudioEvent::setSampleStart( int value )
{
    _sampleStart = value;
}

int BaseAudioEvent::getSampleEnd()
{
    return _sampleEnd;
}

void BaseAudioEvent::setSampleEnd( int value )
{
    _sampleEnd = value;
}

bool BaseAudioEvent::getLoopeable()
{
    return _loopeable;
}

void BaseAudioEvent::setLoopeable( bool value )
{
    _loopeable = value;

    if ( _buffer != 0 )
        _buffer->loopeable = _loopeable;
}

bool BaseAudioEvent::deletable()
{
    return _deleteMe;
}

void BaseAudioEvent::setDeletable( bool value )
{
    _deleteMe = value;
}

bool BaseAudioEvent::isEnabled()
{
    return _enabled;
}

void BaseAudioEvent::setEnabled( bool value )
{
    _enabled = value;
}

void BaseAudioEvent::lock()
{
    _locked = true;
}

void BaseAudioEvent::unlock()
{
    _locked = false;

    if ( _updateAfterUnlock )
    {
        // override in subclass for custom update-logic
    }
    _updateAfterUnlock = false;
}

bool BaseAudioEvent::isLocked()
{
    return _locked;
}

void BaseAudioEvent::mixBuffer( AudioBuffer* outputBuffer, int bufferPos,
                                int minBufferPosition, int maxBufferPosition,
                                bool loopStarted, int loopOffset, bool useChannelRange )
{
    lock(); // prevents buffer mutations (from outside threads) during this read cycle

    // read from the pre-cached buffer for sequenced notes

    int startOffset  = getSampleStart();
    int endOffset    = getSampleEnd();
    int sampleLength = getSampleLength();
    int bufferSize   = outputBuffer->bufferSize;

    for ( int i = 0; i < bufferSize; ++i )
    {
        int readPointer = i + bufferPos;

        // over the max position ? read from the start ( implies that sequence has started loop )
        if ( readPointer >= maxBufferPosition )
        {
            if ( useChannelRange )  // TODO: channels use a min buffer position too ? (currently drummachine only)
                readPointer -= maxBufferPosition;

            else if ( !loopStarted )
                readPointer -= ( maxBufferPosition - minBufferPosition );
        }

        if ( readPointer >= startOffset && readPointer <= endOffset )
        {
            // mind the offset ! ( cached buffer starts at 0 while
            // the startOffset defines where the event is positioned in the sequencer )
            readPointer -= startOffset;

            for ( int c = 0, ca = _buffer->amountOfChannels; c < ca; ++c )
            {
                SAMPLE_TYPE* srcBuffer = _buffer->getBufferForChannel( c );
                SAMPLE_TYPE* tgtBuffer = outputBuffer->getBufferForChannel( c );

                tgtBuffer[ i ] += srcBuffer[ readPointer ];
            }
        }
        else
        {
            if ( loopStarted && i >= loopOffset )
            {
                readPointer = minBufferPosition + ( i - loopOffset );

                if ( readPointer >= startOffset && readPointer <= endOffset )
                {
                    readPointer -= startOffset;

                    for ( int c = 0, ca = _buffer->amountOfChannels; c < ca; ++c )
                    {
                        SAMPLE_TYPE* srcBuffer = _buffer->getBufferForChannel( c );
                        SAMPLE_TYPE* tgtBuffer = outputBuffer->getBufferForChannel( c );

                        tgtBuffer[ i ] += srcBuffer[ readPointer ];
                    }
                }
            }
        }
    }
    unlock();   // release lock
}

AudioBuffer* BaseAudioEvent::getBuffer()
{
    return _buffer;
}

AudioBuffer* BaseAudioEvent::synthesize( int aBufferLength )
{
    // override in subclass as this memory allocation requires cleanup
    // (and basically contains nothing but silence ;-) ... !

    return new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, aBufferLength );
}

/* protected methods */

void BaseAudioEvent::destroy()
{
    destroyBuffer();
}

void BaseAudioEvent::destroyBuffer()
{
    if ( _destroyableBuffer && _buffer != 0 )
    {
        delete _buffer;
        _buffer = 0;
    }
}
<commit_msg>fixed bug where stereo events would crash an audio engine configured for mono output<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2014 Igor Zinken - http://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "baseaudioevent.h"
#include "../global.h"
#include "../utilities/utils.h"

// constructor / destructor

BaseAudioEvent::BaseAudioEvent()
{
    _buffer            = 0;
    _enabled           = true;
    _destroyableBuffer = true;
    _loopeable         = false;
    _locked            = false;
}

BaseAudioEvent::~BaseAudioEvent()
{
    // DebugTool::log( "BaseAudioEvent::destructor" );
    destroy();
}

/* public methods */

int BaseAudioEvent::getSampleLength()
{
    return _sampleLength;
}

void BaseAudioEvent::setSampleLength( int value )
{
    _sampleLength = value;
}

int BaseAudioEvent::getSampleStart()
{
    return _sampleStart;
}

void BaseAudioEvent::setSampleStart( int value )
{
    _sampleStart = value;
}

int BaseAudioEvent::getSampleEnd()
{
    return _sampleEnd;
}

void BaseAudioEvent::setSampleEnd( int value )
{
    _sampleEnd = value;
}

bool BaseAudioEvent::getLoopeable()
{
    return _loopeable;
}

void BaseAudioEvent::setLoopeable( bool value )
{
    _loopeable = value;

    if ( _buffer != 0 )
        _buffer->loopeable = _loopeable;
}

bool BaseAudioEvent::deletable()
{
    return _deleteMe;
}

void BaseAudioEvent::setDeletable( bool value )
{
    _deleteMe = value;
}

bool BaseAudioEvent::isEnabled()
{
    return _enabled;
}

void BaseAudioEvent::setEnabled( bool value )
{
    _enabled = value;
}

void BaseAudioEvent::lock()
{
    _locked = true;
}

void BaseAudioEvent::unlock()
{
    _locked = false;

    if ( _updateAfterUnlock )
    {
        // override in subclass for custom update-logic
    }
    _updateAfterUnlock = false;
}

bool BaseAudioEvent::isLocked()
{
    return _locked;
}

void BaseAudioEvent::mixBuffer( AudioBuffer* outputBuffer, int bufferPos,
                                int minBufferPosition, int maxBufferPosition,
                                bool loopStarted, int loopOffset, bool useChannelRange )
{
    lock(); // prevents buffer mutations (from outside threads) during this read cycle

    // read from the pre-cached buffer for sequenced notes

    int startOffset  = getSampleStart();
    int endOffset    = getSampleEnd();
    int sampleLength = getSampleLength();
    int bufferSize   = outputBuffer->bufferSize;

    // if the output channel amount differs from this events channel amount, we might
    // potentially have a bad time (e.g. engine has mono output while this event is stereo)
    // ideally events should never hold more channels than AudioEngineProps::OUTPUT_CHANNELS

    int outputChannels = std::min( _buffer->amountOfChannels, outputBuffer->amountOfChannels );

    for ( int i = 0; i < bufferSize; ++i )
    {
        int readPointer = i + bufferPos;

        // over the max position ? read from the start ( implies that sequence has started loop )
        if ( readPointer >= maxBufferPosition )
        {
            if ( useChannelRange )  // TODO: channels use a min buffer position too ? (currently drummachine only)
                readPointer -= maxBufferPosition;

            else if ( !loopStarted )
                readPointer -= ( maxBufferPosition - minBufferPosition );
        }

        if ( readPointer >= startOffset && readPointer <= endOffset )
        {
            // mind the offset ! ( cached buffer starts at 0 while
            // the startOffset defines where the event is positioned in the sequencer )
            readPointer -= startOffset;

            for ( int c = 0; c < outputChannels; ++c )
            {
                SAMPLE_TYPE* srcBuffer = _buffer->getBufferForChannel( c );
                SAMPLE_TYPE* tgtBuffer = outputBuffer->getBufferForChannel( c );

                tgtBuffer[ i ] += srcBuffer[ readPointer ];
            }
        }
        else
        {
            if ( loopStarted && i >= loopOffset )
            {
                readPointer = minBufferPosition + ( i - loopOffset );

                if ( readPointer >= startOffset && readPointer <= endOffset )
                {
                    readPointer -= startOffset;

                    for ( int c = 0, ca = _buffer->amountOfChannels; c < ca; ++c )
                    {
                        SAMPLE_TYPE* srcBuffer = _buffer->getBufferForChannel( c );
                        SAMPLE_TYPE* tgtBuffer = outputBuffer->getBufferForChannel( c );

                        tgtBuffer[ i ] += srcBuffer[ readPointer ];
                    }
                }
            }
        }
    }
    unlock();   // release lock
}

AudioBuffer* BaseAudioEvent::getBuffer()
{
    return _buffer;
}

AudioBuffer* BaseAudioEvent::synthesize( int aBufferLength )
{
    // override in subclass as this memory allocation requires cleanup
    // (and basically contains nothing but silence ;-) ... !

    return new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, aBufferLength );
}

/* protected methods */

void BaseAudioEvent::destroy()
{
    destroyBuffer();
}

void BaseAudioEvent::destroyBuffer()
{
    if ( _destroyableBuffer && _buffer != 0 )
    {
        delete _buffer;
        _buffer = 0;
    }
}
<|endoftext|>


<commit_before>#include "KEngine/Core/EntityManager.hpp"

#include "KEngine/Log/Log.hpp"

namespace ke
{
    void EntityManager::update(ke::Time elapsedTime)
    {
        for (auto & entityIdPair : this->entityMap)
        {
            entityIdPair.second->updateAll(elapsedTime);
        }
    }

    ke::EntityWptr EntityManager::newEntity(ke::EntityId newEntityId)
    {
        if (newEntityId != ke::INVALID_ENTITY_ID)
        {
            if (!this->findEntityById(newEntityId).expired())
            {
                ke::Log::instance()->critical("The specified entity ID({}) for a new entity already exists in an existing entity.", newEntityId);
            }
        }
        else
        {
            newEntityId = ke::Entity::newId();
        }
        auto entity = ke::makeEntity(newEntityId);
        this->addEntity(entity);
        return entity;
    }

    void EntityManager::removeEntity(ke::EntityId entityId)
    {
        auto entityIt = this->entityMap.find(entityId);
        if (entityIt != this->entityMap.end())
        {
            auto entity = entityIt->second;
            this->entityMap.erase(entityIt);
            entity->destory();
            entity.reset();
        }
        else
        {
#if defined(KE_DEBUG)
            ke::Log::instance()->warn("Entity with ID({}) not found.", entityId);
#endif
        }
    }

    ke::EntityWptr EntityManager::findEntityById(ke::EntityId entityId)
    {
        auto entityIt = this->entityMap.find(entityId);
        return entityIt == this->entityMap.end() ? nullptr : (*entityIt).second;
    }

}<commit_msg>fix bad check for existing entities<commit_after>#include "KEngine/Core/EntityManager.hpp"

#include "KEngine/Log/Log.hpp"

namespace ke
{
    void EntityManager::update(ke::Time elapsedTime)
    {
        for (auto & entityIdPair : this->entityMap)
        {
            entityIdPair.second->updateAll(elapsedTime);
        }
    }

    ke::EntityWptr EntityManager::newEntity(ke::EntityId newEntityId)
    {
        if (newEntityId != ke::INVALID_ENTITY_ID)
        {
            if (auto entity = this->findEntityById(newEntityId); !entity.expired())
            {
                ke::Log::instance()->critical("The specified entity ID({}) for a new entity already exists in an existing entity.", newEntityId);
                assert(entity.expired());
            }
        }
        else
        {
            newEntityId = ke::Entity::newId();
        }
        auto entity = ke::makeEntity(newEntityId);
        this->addEntity(entity);
        return entity;
    }

    void EntityManager::removeEntity(ke::EntityId entityId)
    {
        auto entityIt = this->entityMap.find(entityId);
        if (entityIt != this->entityMap.end())
        {
            auto entity = entityIt->second;
            this->entityMap.erase(entityIt);
            entity->destory();
            entity.reset();
        }
        else
        {
#if defined(KE_DEBUG)
            ke::Log::instance()->warn("Entity with ID({}) not found.", entityId);
#endif
        }
    }

    ke::EntityWptr EntityManager::findEntityById(ke::EntityId entityId)
    {
        auto entityIt = this->entityMap.find(entityId);
        return entityIt == this->entityMap.end() ? nullptr : (*entityIt).second;
    }

}<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "TextureImage.h"

#include "Magnum/BufferImage.h"
#include "Magnum/Framebuffer.h"
#include "Magnum/Image.h"
#include "Magnum/Texture.h"

#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
#include <Corrade/Utility/Resource.h>

#include "Magnum/AbstractShaderProgram.h"
#include "Magnum/Mesh.h"
#include "Magnum/PixelFormat.h"
#include "Magnum/Shader.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Version.h"

#ifdef MAGNUM_BUILD_STATIC
static void importDebugToolsResources() {
    CORRADE_RESOURCE_INITIALIZE(MagnumDebugTools_RESOURCES)
}
#endif
#endif

namespace Magnum { namespace DebugTools {

#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
namespace {

class FloatReinterpretShader: public AbstractShaderProgram {
    public:
        explicit FloatReinterpretShader();

        FloatReinterpretShader& setTexture(Texture2D& texture, Int level) {
            texture.bind(0);
            setUniform(levelUniform, level);
            return *this;
        }

    private:
        Int levelUniform;
};

FloatReinterpretShader::FloatReinterpretShader() {
    #ifdef MAGNUM_BUILD_STATIC
    /* Import resources on static build, if not already */
    if(!Utility::Resource::hasGroup("MagnumDebugTools"))
        importShaderResources();
    #endif
    Utility::Resource rs{"MagnumDebugTools"};

    Shader vert{Version::GLES300, Shader::Type::Vertex};
    Shader frag{Version::GLES300, Shader::Type::Fragment};
    vert.addSource(rs.get("TextureImage.vert"));
    frag.addSource(rs.get("TextureImage.frag"));

    CORRADE_INTERNAL_ASSERT(Shader::compile({vert, frag}));
    attachShaders({vert, frag});

    CORRADE_INTERNAL_ASSERT(link());

    levelUniform = uniformLocation("level");
    setUniform(uniformLocation("textureData"), 0);
}

}
#endif

void textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, Image2D& image) {
    #ifdef MAGNUM_TARGET_GLES
    if(image.type() == PixelType::Float) {
        const PixelFormat imageFormat = image.format();
        TextureFormat textureFormat;
        PixelFormat reinterpretFormat;
        switch(imageFormat) {
            case PixelFormat::Red:
                textureFormat = TextureFormat::R32UI;
                reinterpretFormat = PixelFormat::RedInteger;
                break;
            case PixelFormat::RG:
                textureFormat = TextureFormat::RG32UI;
                reinterpretFormat = PixelFormat::RGInteger;
                break;
            case PixelFormat::RGB:
                textureFormat = TextureFormat::RGB32UI;
                reinterpretFormat = PixelFormat::RGBInteger;
                break;
            case PixelFormat::RGBA:
                textureFormat = TextureFormat::RGBA32UI;
                reinterpretFormat = PixelFormat::RGBAInteger;
                break;
            default:
                CORRADE_ASSERT(false, "DebugTools::textureSubImage(): unsupported pixel format" << image.format(), );
        }

        Texture2D output;
        output.setStorage(1, textureFormat, range.max());

        Framebuffer fb{range};
        fb.attachTexture(Framebuffer::ColorAttachment{0}, output, 0)
          .bind();

        CORRADE_INTERNAL_ASSERT(fb.checkStatus(FramebufferTarget::Draw) == Framebuffer::Status::Complete);
        CORRADE_INTERNAL_ASSERT(fb.checkStatus(FramebufferTarget::Read) == Framebuffer::Status::Complete);

        FloatReinterpretShader shader;
        shader.setTexture(texture, level);

        Mesh mesh;
        mesh.setCount(3)
            .draw(shader);

        /* release() needs to be called after querying the size to avoid zeroing it out */
        {
            Vector2i imageSize = image.size();
            image.setData(image.storage(), reinterpretFormat, PixelType::UnsignedInt, imageSize, image.release());
        }

        fb.read(range, image);

        /* release() needs to be called after querying the size to avoid zeroing it out */
        {
            Vector2i imageSize = image.size();
            image.setData(image.storage(), imageFormat, PixelType::Float, imageSize, image.release());
        }
        return;
    }
    #endif

    Framebuffer fb{range};
    fb.attachTexture(Framebuffer::ColorAttachment{0}, texture, level)
      .read(range, image);
}

void textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, Image2D& image) {
    Framebuffer fb{range};
    fb.attachCubeMapTexture(Framebuffer::ColorAttachment{0}, texture, coordinate, level)
      .read(range, image);
}

#ifndef MAGNUM_TARGET_GLES2
void textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, BufferImage2D& image, const BufferUsage usage) {
    Framebuffer fb{range};
    fb.attachTexture(Framebuffer::ColorAttachment{0}, texture, level)
      .read(range, image, usage);
}

void textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, BufferImage2D& image, const BufferUsage usage) {
    Framebuffer fb{range};
    fb.attachCubeMapTexture(Framebuffer::ColorAttachment{0}, texture, coordinate, level)
      .read(range, image, usage);
}
#endif

Image2D textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, Image2D&& image) {
    textureSubImage(texture, level, range, image);
    return std::move(image);
}

Image2D textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, Image2D&& image) {
    textureSubImage(texture, coordinate, level, range, image);
    return std::move(image);
}

#ifndef MAGNUM_TARGET_GLES2
BufferImage2D textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) {
    textureSubImage(texture, level, range, image, usage);
    return std::move(image);
}

BufferImage2D textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) {
    textureSubImage(texture, coordinate, level, range, image, usage);
    return std::move(image);
}
#endif

}}
<commit_msg>DebugTools: fix static build on ES.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "TextureImage.h"

#include "Magnum/BufferImage.h"
#include "Magnum/Framebuffer.h"
#include "Magnum/Image.h"
#include "Magnum/Texture.h"

#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
#include <Corrade/Utility/Resource.h>

#include "Magnum/AbstractShaderProgram.h"
#include "Magnum/Mesh.h"
#include "Magnum/PixelFormat.h"
#include "Magnum/Shader.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Version.h"

#ifdef MAGNUM_BUILD_STATIC
static void importDebugToolsResources() {
    CORRADE_RESOURCE_INITIALIZE(MagnumDebugTools_RESOURCES)
}
#endif
#endif

namespace Magnum { namespace DebugTools {

#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
namespace {

class FloatReinterpretShader: public AbstractShaderProgram {
    public:
        explicit FloatReinterpretShader();

        FloatReinterpretShader& setTexture(Texture2D& texture, Int level) {
            texture.bind(0);
            setUniform(levelUniform, level);
            return *this;
        }

    private:
        Int levelUniform;
};

FloatReinterpretShader::FloatReinterpretShader() {
    #ifdef MAGNUM_BUILD_STATIC
    /* Import resources on static build, if not already */
    if(!Utility::Resource::hasGroup("MagnumDebugTools"))
        importDebugToolsResources();
    #endif
    Utility::Resource rs{"MagnumDebugTools"};

    Shader vert{Version::GLES300, Shader::Type::Vertex};
    Shader frag{Version::GLES300, Shader::Type::Fragment};
    vert.addSource(rs.get("TextureImage.vert"));
    frag.addSource(rs.get("TextureImage.frag"));

    CORRADE_INTERNAL_ASSERT(Shader::compile({vert, frag}));
    attachShaders({vert, frag});

    CORRADE_INTERNAL_ASSERT(link());

    levelUniform = uniformLocation("level");
    setUniform(uniformLocation("textureData"), 0);
}

}
#endif

void textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, Image2D& image) {
    #ifdef MAGNUM_TARGET_GLES
    if(image.type() == PixelType::Float) {
        const PixelFormat imageFormat = image.format();
        TextureFormat textureFormat;
        PixelFormat reinterpretFormat;
        switch(imageFormat) {
            case PixelFormat::Red:
                textureFormat = TextureFormat::R32UI;
                reinterpretFormat = PixelFormat::RedInteger;
                break;
            case PixelFormat::RG:
                textureFormat = TextureFormat::RG32UI;
                reinterpretFormat = PixelFormat::RGInteger;
                break;
            case PixelFormat::RGB:
                textureFormat = TextureFormat::RGB32UI;
                reinterpretFormat = PixelFormat::RGBInteger;
                break;
            case PixelFormat::RGBA:
                textureFormat = TextureFormat::RGBA32UI;
                reinterpretFormat = PixelFormat::RGBAInteger;
                break;
            default:
                CORRADE_ASSERT(false, "DebugTools::textureSubImage(): unsupported pixel format" << image.format(), );
        }

        Texture2D output;
        output.setStorage(1, textureFormat, range.max());

        Framebuffer fb{range};
        fb.attachTexture(Framebuffer::ColorAttachment{0}, output, 0)
          .bind();

        CORRADE_INTERNAL_ASSERT(fb.checkStatus(FramebufferTarget::Draw) == Framebuffer::Status::Complete);
        CORRADE_INTERNAL_ASSERT(fb.checkStatus(FramebufferTarget::Read) == Framebuffer::Status::Complete);

        FloatReinterpretShader shader;
        shader.setTexture(texture, level);

        Mesh mesh;
        mesh.setCount(3)
            .draw(shader);

        /* release() needs to be called after querying the size to avoid zeroing it out */
        {
            Vector2i imageSize = image.size();
            image.setData(image.storage(), reinterpretFormat, PixelType::UnsignedInt, imageSize, image.release());
        }

        fb.read(range, image);

        /* release() needs to be called after querying the size to avoid zeroing it out */
        {
            Vector2i imageSize = image.size();
            image.setData(image.storage(), imageFormat, PixelType::Float, imageSize, image.release());
        }
        return;
    }
    #endif

    Framebuffer fb{range};
    fb.attachTexture(Framebuffer::ColorAttachment{0}, texture, level)
      .read(range, image);
}

void textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, Image2D& image) {
    Framebuffer fb{range};
    fb.attachCubeMapTexture(Framebuffer::ColorAttachment{0}, texture, coordinate, level)
      .read(range, image);
}

#ifndef MAGNUM_TARGET_GLES2
void textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, BufferImage2D& image, const BufferUsage usage) {
    Framebuffer fb{range};
    fb.attachTexture(Framebuffer::ColorAttachment{0}, texture, level)
      .read(range, image, usage);
}

void textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, BufferImage2D& image, const BufferUsage usage) {
    Framebuffer fb{range};
    fb.attachCubeMapTexture(Framebuffer::ColorAttachment{0}, texture, coordinate, level)
      .read(range, image, usage);
}
#endif

Image2D textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, Image2D&& image) {
    textureSubImage(texture, level, range, image);
    return std::move(image);
}

Image2D textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, Image2D&& image) {
    textureSubImage(texture, coordinate, level, range, image);
    return std::move(image);
}

#ifndef MAGNUM_TARGET_GLES2
BufferImage2D textureSubImage(Texture2D& texture, const Int level, const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) {
    textureSubImage(texture, level, range, image, usage);
    return std::move(image);
}

BufferImage2D textureSubImage(CubeMapTexture& texture, const CubeMapCoordinate coordinate, const Int level, const Range2Di& range, BufferImage2D&& image, const BufferUsage usage) {
    textureSubImage(texture, coordinate, level, range, image, usage);
    return std::move(image);
}
#endif

}}
<|endoftext|>


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

    Written by David Raffelt, 06/07/11.

    This file is part of MRtrix.

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

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

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

*/

#include "command.h"
#include "memory.h"
#include "progressbar.h"
#include "image/threaded_loop.h"
#include "image/voxel.h"
#include "image/buffer.h"
#include "image/buffer_preload.h"
#include "math/SH.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "David Raffelt (d.raffelt@brain.org.au)";

  DESCRIPTION
    + "perform a spherical convolution";

  ARGUMENTS
    + Argument ("SH", "the input spherical harmonics coefficients image.").type_image_in ()
    + Argument ("response", "the convolution kernel (response function)").type_file_in ()
    + Argument ("SH", "the output spherical harmonics coefficients image.").type_image_out ();

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

    + Image::Stride::StrideOption;
}

typedef float value_type;

class SDeconvFunctor {
  public:
  SDeconvFunctor (Image::BufferPreload<value_type>& in,
                  Image::Buffer<value_type>& out,
                  std::unique_ptr<Image::Buffer<bool> >& mask,
                  const Math::Vector<value_type>& response) :
                    input_vox (in),
                    output_vox (out),
                    mask_vox_ptr (mask ? new Image::Buffer<bool>::voxel_type (*mask) : nullptr),
                    response (response) { }

    void operator() (const Image::Iterator& pos) {
      if (mask_vox_ptr) {
        Image::voxel_assign (*mask_vox_ptr, pos);
        if (!mask_vox_ptr->value()) {
          for (output_vox[3] = 0; output_vox[3] < output_vox.dim(3); ++output_vox[3])
            output_vox.value() = 0.0;
          return;
        }
      }
      Image::voxel_assign (input_vox, pos);
      input_vox[3] = 0;
      Math::Vector<value_type> input (input_vox.address(), input_vox.dim(3));
      Math::Vector<value_type> output (output_vox.dim(3));
      Math::SH::sconv (output, response, input);
      Image::voxel_assign (output_vox, pos);
      for (output_vox[3] = 0; output_vox[3] < output_vox.dim(3); ++output_vox[3])
        output_vox.value() = output[output_vox[3]];

    }

  protected:
    Image::BufferPreload<value_type>::voxel_type input_vox;
    Image::Buffer<value_type>::voxel_type output_vox;
    copy_ptr<Image::Buffer<bool>::voxel_type> mask_vox_ptr;
    Math::Vector<value_type> response;
};

void run() {

  Image::Header input_SH_header (argument[0]);
  Math::SH::check (input_SH_header);
  Image::BufferPreload<value_type> input_buf (input_SH_header, Image::Stride::contiguous_along_axis (3));

  Math::Vector<value_type> responseSH;
  responseSH.load (argument[1]);
  Math::Vector<value_type> responseRH;
  Math::SH::SH2RH (responseRH, responseSH);

  std::unique_ptr<Image::Buffer<bool> > mask_buf;
  Options opt = get_options ("mask");
  if (opt.size()) {
    mask_buf.reset (new Image::Buffer<bool> (opt[0][0]));
    Image::check_dimensions (*mask_buf, input_buf, 0, 3);
  }

  Image::Header output_SH_header (input_SH_header);
  Image::Stride::set_from_command_line (output_SH_header, Image::Stride::contiguous_along_axis (3));
  Image::Buffer<value_type> output_SH_buf (argument[2], output_SH_header);

  SDeconvFunctor sconv (input_buf, output_SH_buf, mask_buf, responseRH);
  Image::ThreadedLoop loop ("performing convolution...", input_buf, 0, 3, 2);
  loop.run (sconv);
}
<commit_msg>shconv: Fix masked output<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by David Raffelt, 06/07/11.

    This file is part of MRtrix.

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

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

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

*/

#include "command.h"
#include "memory.h"
#include "progressbar.h"
#include "image/threaded_loop.h"
#include "image/voxel.h"
#include "image/buffer.h"
#include "image/buffer_preload.h"
#include "math/SH.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "David Raffelt (d.raffelt@brain.org.au)";

  DESCRIPTION
    + "perform a spherical convolution";

  ARGUMENTS
    + Argument ("SH", "the input spherical harmonics coefficients image.").type_image_in ()
    + Argument ("response", "the convolution kernel (response function)").type_file_in ()
    + Argument ("SH", "the output spherical harmonics coefficients image.").type_image_out ();

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

    + Image::Stride::StrideOption;
}

typedef float value_type;

class SDeconvFunctor {
  public:
  SDeconvFunctor (Image::BufferPreload<value_type>& in,
                  Image::Buffer<value_type>& out,
                  std::unique_ptr<Image::Buffer<bool> >& mask,
                  const Math::Vector<value_type>& response) :
                    input_vox (in),
                    output_vox (out),
                    mask_vox_ptr (mask ? new Image::Buffer<bool>::voxel_type (*mask) : nullptr),
                    response (response) { }

    void operator() (const Image::Iterator& pos) {
      Image::voxel_assign (output_vox, pos);
      if (mask_vox_ptr) {
        Image::voxel_assign (*mask_vox_ptr, pos);
        if (!mask_vox_ptr->value()) {
          for (output_vox[3] = 0; output_vox[3] < output_vox.dim(3); ++output_vox[3])
            output_vox.value() = 0.0;
          return;
        }
      }
      Image::voxel_assign (input_vox, pos);
      input_vox[3] = 0;
      Math::Vector<value_type> input (input_vox.address(), input_vox.dim(3));
      Math::Vector<value_type> output (output_vox.dim(3));
      Math::SH::sconv (output, response, input);
      for (output_vox[3] = 0; output_vox[3] < output_vox.dim(3); ++output_vox[3])
        output_vox.value() = output[output_vox[3]];
    }

  protected:
    Image::BufferPreload<value_type>::voxel_type input_vox;
    Image::Buffer<value_type>::voxel_type output_vox;
    copy_ptr<Image::Buffer<bool>::voxel_type> mask_vox_ptr;
    Math::Vector<value_type> response;
};

void run() {

  Image::Header input_SH_header (argument[0]);
  Math::SH::check (input_SH_header);
  Image::BufferPreload<value_type> input_buf (input_SH_header, Image::Stride::contiguous_along_axis (3));

  Math::Vector<value_type> responseSH;
  responseSH.load (argument[1]);
  Math::Vector<value_type> responseRH;
  Math::SH::SH2RH (responseRH, responseSH);

  std::unique_ptr<Image::Buffer<bool> > mask_buf;
  Options opt = get_options ("mask");
  if (opt.size()) {
    mask_buf.reset (new Image::Buffer<bool> (opt[0][0]));
    Image::check_dimensions (*mask_buf, input_buf, 0, 3);
  }

  Image::Header output_SH_header (input_SH_header);
  Image::Stride::set_from_command_line (output_SH_header, Image::Stride::contiguous_along_axis (3));
  Image::Buffer<value_type> output_SH_buf (argument[2], output_SH_header);

  SDeconvFunctor sconv (input_buf, output_SH_buf, mask_buf, responseRH);
  Image::ThreadedLoop loop ("performing convolution...", input_buf, 0, 3, 2);
  loop.run (sconv);
}
<|endoftext|>


<commit_before>// Copyright Louis Dionne 2015
// Distributed under the Boost Software License, Version 1.0.

#include <boost/hana.hpp>
namespace hana = boost::hana;

template <typename ...Options>
struct option_maker {
  hana::_tuple<Options...> options;
};

template <typename ...Attributes>
struct _option { hana::_tuple<Attributes...> attributes; };

template <typename ...Attributes>
auto option(Attributes ...attributes)
{ return _option<Attributes...>{{attributes...}}; }

template <typename Description>
struct _banner { Description description; };

template <typename Description>
auto banner(Description description)
{ return _banner<Description>{description}; }

template <typename ...Attributes>
struct _check { hana::_tuple<Attributes...> attributes; };

template <typename ...Attributes>
auto check(Attributes ...attributes)
{ return _check<Attributes...>{{attributes...}}; }

template <typename ...Options, typename Option>
constexpr option_maker<Options..., Option> operator|(option_maker<Options...> options, Option opt) {
  return {{hana::append(options.options, opt)}};
}

auto name = [](auto s) { return hana::make_pair("name", s); };
auto description = [](auto s) { return hana::make_pair("description", s); };
auto default_ = [](auto s) { return hana::make_pair("default", s); };

auto options = option_maker<>{} | banner(
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,"
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo"
"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse"
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non"
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
| option(name("ignore"), description("Ignore incorrect values"))
| option(name("iters"), description("Number of iterations"), default_(5))

| option(name("volume"), description("Volume level"), default_(3.0))
| check([](auto opts) {
    if (opts["volume"] < 0)
      opts.die("volume must be non-negative");
  })

| option(name("file"), description("Extra data filename to read in"), hana::type<int>)
| check([](auto opts) {
    if (opts["file"] && !opts["file"].exists())
      opts.die("file must exists");
  })
;

int main(int argc, char *argv[]) {
  // options.parse(argv, argv + argc);
}
<commit_msg>Use _s user-defined literals for strings<commit_after>// Copyright Louis Dionne 2015
// Distributed under the Boost Software License, Version 1.0.

#include <boost/hana.hpp>
#include <string>
namespace hana = boost::hana;

template <typename CharT, CharT ...s>
constexpr auto operator"" _s()
{ return hana::string<s...>; }

template <typename ...Options>
struct option_maker {
  hana::_tuple<Options...> options;
};

template <typename ...Attributes>
struct _option { hana::_tuple<Attributes...> attributes; };

template <typename ...Attributes>
auto option(Attributes ...attributes)
{ return _option<Attributes...>{{attributes...}}; }

template <typename Description>
struct _banner { Description description; };

template <typename Description>
auto banner(Description description)
{ return _banner<Description>{description}; }

template <typename ...Attributes>
struct _check { hana::_tuple<Attributes...> attributes; };

template <typename ...Attributes>
auto check(Attributes ...attributes)
{ return _check<Attributes...>{{attributes...}}; }

template <typename ...Options, typename Option>
constexpr option_maker<Options..., Option> operator|(option_maker<Options...> options, Option opt) {
  return {{hana::append(options.options, opt)}};
}

auto name = [](auto s) { return hana::make_pair("name"_s, s); };
auto description = [](auto s) { return hana::make_pair("description"_s, s); };
auto default_ = [](auto s) { return hana::make_pair("default"_s, s); };

auto options = option_maker<>{} | banner(
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"_s
)
| option(name("ignore"_s), description("Ignore incorrect values"_s))
| option(name("iters"_s), description("Number of iterations"_s), default_(5))

| option(name("volume"_s), description("Volume level"_s), default_(3.0))
| check([](auto opts) {
    if (opts["volume"_s] < 0)
      opts.die("volume must be non-negative");
  })

| option(name("file"_s), description("Extra data filename to read in"_s), hana::type<std::string>)
| check([](auto opts) {
    if (opts["file"_s] && !opts["file"_s].exists())
      opts.die("file must exists");
  })
;

int main(int argc, char *argv[]) {
  // options.parse(argv, argv + argc);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2013, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"

#include "libtorrent/file_storage.hpp"

using namespace libtorrent;

void setup_test_storage(file_storage& st)
{
	st.add_file("test/a", 10000);
	st.add_file("test/b", 20000);
	st.add_file("test/c/a", 30000);
	st.add_file("test/c/b", 40000);

	st.set_piece_length(0x4000);
	st.set_num_pieces((st.total_size() + st.piece_length() - 1) / 0x4000);

	TEST_EQUAL(st.file_name(0), "a");
	TEST_EQUAL(st.file_name(1), "b");
	TEST_EQUAL(st.file_name(2), "a");
	TEST_EQUAL(st.file_name(3), "b");
	TEST_EQUAL(st.name(), "test");

	TEST_EQUAL(st.file_path(0), "test/a");
	TEST_EQUAL(st.file_path(1), "test/b");
	TEST_EQUAL(st.file_path(2), "test/c/a");
	TEST_EQUAL(st.file_path(3), "test/c/b");

	TEST_EQUAL(st.file_size(0), 10000);
	TEST_EQUAL(st.file_size(1), 20000);
	TEST_EQUAL(st.file_size(2), 30000);
	TEST_EQUAL(st.file_size(3), 40000);

	TEST_EQUAL(st.file_offset(0), 0);
	TEST_EQUAL(st.file_offset(1), 10000);
	TEST_EQUAL(st.file_offset(2), 30000);
	TEST_EQUAL(st.file_offset(3), 60000);

	TEST_EQUAL(st.total_size(), 100000);
	TEST_EQUAL(st.piece_length(), 0x4000);
	printf("%d\n", st.num_pieces());
	TEST_EQUAL(st.num_pieces(), (100000 + 0x3fff) / 0x4000);
}

int test_main()
{
	{
		file_storage st;
		setup_test_storage(st);

		st.rename_file(0, "test/c/d");
		TEST_EQUAL(st.file_path(0, "./"), "./test/c/d");

		st.rename_file(0, "/tmp/a");
		TEST_EQUAL(st.file_path(0, "./"), "/tmp/a");
	}

	{
		file_storage st;
		st.add_file("a", 10000);

		st.rename_file(0, "test/c/d");
		TEST_EQUAL(st.file_path(0, "./"), "./test/c/d");

		st.rename_file(0, "/tmp/a");
		TEST_EQUAL(st.file_path(0, "./"), "/tmp/a");
	}

	{
		file_storage fs;
		fs.set_piece_length(512);
		fs.add_file("temp_storage/test1.tmp", 17);
		fs.add_file("temp_storage/test2.tmp", 612);
		fs.add_file("temp_storage/test3.tmp", 0);
		fs.add_file("temp_storage/test4.tmp", 0);
		fs.add_file("temp_storage/test5.tmp", 3253);
		// size: 3882
		fs.add_file("temp_storage/test6.tmp", 841);
		// size: 4723

		peer_request rq = fs.map_file(0, 0, 10);
		TEST_EQUAL(rq.piece, 0);
		TEST_EQUAL(rq.start, 0);
		TEST_EQUAL(rq.length, 10);
		rq = fs.map_file(5, 0, 10);
		TEST_EQUAL(rq.piece, 7);
		TEST_EQUAL(rq.start, 298);
		TEST_EQUAL(rq.length, 10);
		rq = fs.map_file(5, 0, 1000);
		TEST_EQUAL(rq.piece, 7);
		TEST_EQUAL(rq.start, 298);
		TEST_EQUAL(rq.length, 841);
	}

	return 0;
}

<commit_msg>fix test_file_storage for windows<commit_after>/*

Copyright (c) 2013, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"

#include "libtorrent/file_storage.hpp"

using namespace libtorrent;

void setup_test_storage(file_storage& st)
{
	st.add_file("test/a", 10000);
	st.add_file("test/b", 20000);
	st.add_file("test/c/a", 30000);
	st.add_file("test/c/b", 40000);

	st.set_piece_length(0x4000);
	st.set_num_pieces((st.total_size() + st.piece_length() - 1) / 0x4000);

	TEST_EQUAL(st.file_name(0), "a");
	TEST_EQUAL(st.file_name(1), "b");
	TEST_EQUAL(st.file_name(2), "a");
	TEST_EQUAL(st.file_name(3), "b");
	TEST_EQUAL(st.name(), "test");

	TEST_EQUAL(st.file_path(0), "test/a");
	TEST_EQUAL(st.file_path(1), "test/b");
	TEST_EQUAL(st.file_path(2), "test/c/a");
	TEST_EQUAL(st.file_path(3), "test/c/b");

	TEST_EQUAL(st.file_size(0), 10000);
	TEST_EQUAL(st.file_size(1), 20000);
	TEST_EQUAL(st.file_size(2), 30000);
	TEST_EQUAL(st.file_size(3), 40000);

	TEST_EQUAL(st.file_offset(0), 0);
	TEST_EQUAL(st.file_offset(1), 10000);
	TEST_EQUAL(st.file_offset(2), 30000);
	TEST_EQUAL(st.file_offset(3), 60000);

	TEST_EQUAL(st.total_size(), 100000);
	TEST_EQUAL(st.piece_length(), 0x4000);
	printf("%d\n", st.num_pieces());
	TEST_EQUAL(st.num_pieces(), (100000 + 0x3fff) / 0x4000);
}

int test_main()
{
	{
		file_storage st;
		setup_test_storage(st);

		st.rename_file(0, "test/c/d");
		TEST_EQUAL(st.file_path(0, "./"), "./test/c/d");

#ifdef TORRENT_WINDOWS
		st.rename_file(0, "c:\\tmp\\a");
		TEST_EQUAL(st.file_path(0, "."), "c:\\tmp\\a");
#else
		st.rename_file(0, "/tmp/a");
		TEST_EQUAL(st.file_path(0, "."), "/tmp/a");
#endif
	}

	{
		file_storage st;
		st.add_file("a", 10000);

		st.rename_file(0, "test/c/d");
		TEST_EQUAL(st.file_path(0, "./"), "./test/c/d");

#ifdef TORRENT_WINDOWS
		st.rename_file(0, "c:\\tmp\\a");
		TEST_EQUAL(st.file_path(0, "."), "c:\\tmp\\a");
#else
		st.rename_file(0, "/tmp/a");
		TEST_EQUAL(st.file_path(0, "."), "/tmp/a");
#endif
	}

	{
		file_storage fs;
		fs.set_piece_length(512);
		fs.add_file(combine_path("temp_storage", "test1.tmp"), 17);
		fs.add_file(combine_path("temp_storage", "test2.tmp"), 612);
		fs.add_file(combine_path("temp_storage", "test3.tmp"), 0);
		fs.add_file(combine_path("temp_storage", "test4.tmp"), 0);
		fs.add_file(combine_path("temp_storage", "test5.tmp"), 3253);
		// size: 3882
		fs.add_file(combine_path("temp_storage", "test6.tmp"), 841);
		// size: 4723

		peer_request rq = fs.map_file(0, 0, 10);
		TEST_EQUAL(rq.piece, 0);
		TEST_EQUAL(rq.start, 0);
		TEST_EQUAL(rq.length, 10);
		rq = fs.map_file(5, 0, 10);
		TEST_EQUAL(rq.piece, 7);
		TEST_EQUAL(rq.start, 298);
		TEST_EQUAL(rq.length, 10);
		rq = fs.map_file(5, 0, 1000);
		TEST_EQUAL(rq.piece, 7);
		TEST_EQUAL(rq.start, 298);
		TEST_EQUAL(rq.length, 841);
	}

	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#include <fstream>

#include "base/stringprintf.h"
#include "builder.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "graph_visualizer.h"
#include "nodes.h"
#include "optimizing_unit_test.h"
#include "pretty_printer.h"
#include "ssa_builder.h"
#include "ssa_liveness_analysis.h"
#include "utils/arena_allocator.h"

#include "gtest/gtest.h"

namespace art {

static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);
  HGraphBuilder builder(&allocator);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  HGraph* graph = builder.BuildGraph(*item);
  ASSERT_NE(graph, nullptr);

  graph->BuildDominatorTree();
  graph->FindNaturalLoops();
  SsaLivenessAnalysis liveness(*graph);
  liveness.Analyze();

  ASSERT_EQ(liveness.GetLinearPostOrder().Size(), number_of_blocks);
  for (size_t i = 0; i < number_of_blocks; ++i) {
    ASSERT_EQ(liveness.GetLinearPostOrder().Get(number_of_blocks - i - 1)->GetBlockId(),
              expected_order[i]);
  }
}

TEST(LinearizeTest, CFG1) {
  // Structure of this graph (* are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ******
  //            /   \       *
  //       Block5   Block7  *
  //         |        |     *
  //       Block6   Block3  *
  //               * /   \  *
  //           Block4   Block8

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 5,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00,
    Instruction::RETURN_VOID);

  const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
  TestCode(data, blocks, 9);
}

TEST(LinearizeTest, CFG2) {
  // Structure of this graph (* are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ******
  //            /   \       *
  //       Block3   Block7  *
  //         |        |     *
  //       Block6   Block4  *
  //               * /   \  *
  //           Block5   Block8

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::RETURN_VOID,
    Instruction::IF_EQ, 0xFFFD,
    Instruction::GOTO | 0xFE00);

  const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
  TestCode(data, blocks, 9);
}

TEST(LinearizeTest, CFG3) {
  // Structure of this graph (* are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ******
  //            /   \       *
  //       Block3   Block8  *
  //         |        |     *
  //       Block7   Block5  *
  //                 / *  \ *
  //           Block6  * Block9
  //             |     *
  //           Block4 **
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 4,
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0x0100,
    Instruction::IF_EQ, 0xFFFC,
    Instruction::GOTO | 0xFD00);

  const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
  TestCode(data, blocks, 10);
}

TEST(LinearizeTest, CFG4) {
  // Structure of this graph (* are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2
  //            / *  \
  //       Block6 * Block8
  //         |    *   |
  //       Block7 * Block3 *******
  //              *  /  \        *
  //           Block9   Block10  *
  //                      |      *
  //                    Block4   *
  //                   */    \   *
  //                Block5  Block11
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 7,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00,
    Instruction::RETURN_VOID);

  const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
  TestCode(data, blocks, 12);
}

TEST(LinearizeTest, CFG5) {
  // Structure of this graph (* are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2
  //            / *  \
  //       Block3 * Block8
  //         |    *   |
  //       Block7 * Block4 *******
  //              *  /  \        *
  //           Block9   Block10  *
  //                      |      *
  //                    Block5   *
  //                   */    \   *
  //                Block6  Block11
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::RETURN_VOID,
    Instruction::IF_EQ, 0xFFFD,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00);

  const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
  TestCode(data, blocks, 12);
}

}  // namespace art
<commit_msg>am 9c7703d3: am c006db38: Merge "Workaround for multi-line comment error when compiled with g++."<commit_after>/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#include <fstream>

#include "base/stringprintf.h"
#include "builder.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "graph_visualizer.h"
#include "nodes.h"
#include "optimizing_unit_test.h"
#include "pretty_printer.h"
#include "ssa_builder.h"
#include "ssa_liveness_analysis.h"
#include "utils/arena_allocator.h"

#include "gtest/gtest.h"

namespace art {

static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);
  HGraphBuilder builder(&allocator);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  HGraph* graph = builder.BuildGraph(*item);
  ASSERT_NE(graph, nullptr);

  graph->BuildDominatorTree();
  graph->FindNaturalLoops();
  SsaLivenessAnalysis liveness(*graph);
  liveness.Analyze();

  ASSERT_EQ(liveness.GetLinearPostOrder().Size(), number_of_blocks);
  for (size_t i = 0; i < number_of_blocks; ++i) {
    ASSERT_EQ(liveness.GetLinearPostOrder().Get(number_of_blocks - i - 1)->GetBlockId(),
              expected_order[i]);
  }
}

TEST(LinearizeTest, CFG1) {
  // Structure of this graph (+ are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ++++++
  //            /   \       +
  //       Block5   Block7  +
  //         |        |     +
  //       Block6   Block3  +
  //               + /   \  +
  //           Block4   Block8

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 5,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00,
    Instruction::RETURN_VOID);

  const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
  TestCode(data, blocks, 9);
}

TEST(LinearizeTest, CFG2) {
  // Structure of this graph (+ are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ++++++
  //            /   \       +
  //       Block3   Block7  +
  //         |        |     +
  //       Block6   Block4  +
  //               + /   \  +
  //           Block5   Block8

  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::RETURN_VOID,
    Instruction::IF_EQ, 0xFFFD,
    Instruction::GOTO | 0xFE00);

  const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
  TestCode(data, blocks, 9);
}

TEST(LinearizeTest, CFG3) {
  // Structure of this graph (+ are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2 ++++++
  //            /   \       +
  //       Block3   Block8  +
  //         |        |     +
  //       Block7   Block5  +
  //                 / +  \ +
  //           Block6  + Block9
  //             |     +
  //           Block4 ++
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 4,
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0x0100,
    Instruction::IF_EQ, 0xFFFC,
    Instruction::GOTO | 0xFD00);

  const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
  TestCode(data, blocks, 10);
}

TEST(LinearizeTest, CFG4) {
  /* Structure of this graph (+ are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2
  //            / +  \
  //       Block6 + Block8
  //         |    +   |
  //       Block7 + Block3 +++++++
  //              +  /  \        +
  //           Block9   Block10  +
  //                      |      +
  //                    Block4   +
  //                  + /    \   +
  //                Block5  Block11
  */
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 7,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00,
    Instruction::RETURN_VOID);

  const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
  TestCode(data, blocks, 12);
}

TEST(LinearizeTest, CFG5) {
  /* Structure of this graph (+ are back edges)
  //            Block0
  //              |
  //            Block1
  //              |
  //            Block2
  //            / +  \
  //       Block3 + Block8
  //         |    +   |
  //       Block7 + Block4 +++++++
  //              +  /  \        +
  //           Block9   Block10  +
  //                      |      +
  //                    Block5   +
  //                   +/    \   +
  //                Block6  Block11
  */
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::RETURN_VOID,
    Instruction::IF_EQ, 0xFFFD,
    Instruction::IF_EQ, 0xFFFE,
    Instruction::GOTO | 0xFE00);

  const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
  TestCode(data, blocks, 12);
}

}  // namespace art
<|endoftext|>