text:
/**
* Copyright 2017 BitTorrent Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <okui/config.h>

#include <okui/opengl/Framebuffer.h>
#include <okui/shaders/ColorShader.h>
#include <okui/shaders/DistanceFieldShader.h>
#include <okui/shaders/TextureShader.h>
#include <okui/Application.h>
#include <okui/Color.h>
#include <okui/Point.h>
#include <okui/Rectangle.h>
#include <okui/RenderTarget.h>
#include <okui/Relation.h>
#include <okui/Responder.h>
#include <okui/ShaderCache.h>
#include <okui/TextureHandle.h>
#include <okui/TouchpadFocus.h>
#include <okui/WeakTexture.h>

#include <scraps/AbstractTaskScheduler.h>
#include <scraps/TreeNode.h>
#include <scraps/utility.h>

#include <stdts/optional.h>

#include <gsl.h>

#include <list>
#include <typeindex>
#include <unordered_map>

namespace okui {

class Application;
class BitmapFont;
class Window;

/**
* View rendering can be cached or buffered to a texture. One reason this may be done is to apply post-rendering
* effects such as tinting or reflection. When this is done, the contents of the view are clipped to its bounds.
*/
class View : public Responder, private scraps::TreeNode<View> {
public:
    using Relation = okui::Relation;

    View() = default;
    explicit View(std::string name) : _name{std::move(name)} {}
    View(const View&) = delete;
    View(View&&) = delete;
    View& operator=(const View&) = delete;
    View& operator=(View&&) = delete;

    /**
    * It is an error to destroy a focused view. Remove the view first if needed.
    */
    virtual ~View();

    std::string name() const       { return _name.empty() ? scraps::Demangle(typeid(*this).name()) : _name; }
    void setName(std::string name) { _name = std::move(name); }

    void addSubview(View* view);
    template <typename... Views>
    void addSubviews(View* view, Views&&... views)  { _addSubviews(view, std::forward<Views>(views)...); }
    void addHiddenSubview(View* view);
    void removeSubview(View* view);
    template <typename... Views>
    void removeSubviews(View* view, Views&&... views) { _removeSubviews(view, std::forward<Views>(views)...); }
    void removeSubviews();

    Window* window() const                    { return _window; }
    Application* application() const;

    const View* superview() const             { return parent(); }
    View* superview()                         { return parent(); }
    const std::list<View*>& subviews() const  { return children(); }

    const Rectangle<double>& bounds() const   { return _bounds; }
    math::Vector<double, 2> size() const      { return _bounds.size(); }
    Point<double> position() const            { return _bounds.position(); }

    double width() const                      { return _bounds.width; }
    double height() const                     { return _bounds.height; }

    template <typename... Args>
    void setBounds(Args&&... args)            { _setBounds(Rectangle<double>(std::forward<Args>(args)...)); }

    void setPosition(double x, double y)      { _setBounds({x, y, _bounds.width, _bounds.height}); }
    void setPosition(const Point<double>& p)  { setPosition(p.x, p.y); }

    void setSize(double width, double height) { _setBounds({_bounds.x, _bounds.y, width, height}); }
    void setSize(const math::Vector<double, 2>& s) { setSize(s.x, s.y); }

    Rectangle<double> windowBounds() const;

    /**
    * Sets bounds as a percent of superview bounds (0-1)
    */
    void setBoundsRelative(double x, double y, double width, double height);

    void setInterceptsInteractions(bool intercepts);
    void setInterceptsInteractions(bool intercepts, bool childrenIntercept);
    void setChildrenInterceptInteractions(bool childrenIntercept);

    ShaderCache* shaderCache();

    void setIsVisible(bool isVisible = true);
    bool isVisible() const { return _isVisible; }

    void show() { setIsVisible(); }
    void hide() { setIsVisible(false); }

    /**
    * Allows scaling of the view by a particular factor.
    */
    void setScale(double scale) { setScale(scale, scale); }
    void setScale(double scaleX, double scaleY);

    /**
    * Sets the view's background color.
    */
    void setBackgroundColor(const Color& color) { _backgroundColor = color; }
    const Color& backgroundColor() const        { return _backgroundColor; }

    /**
    * Sets the view's tint. If this is anything but opaque white, this is a post-rendering effect that
    * clips the view's contents.
    */
    void setTintColor(const Color& color);
    const Color& tintColor() const        { return _tintColor; }

    /**
    * Sets the view's opacity. If this is anything but 1, this is a post-rendering effect that
    * clips the view's contents.
    *
    * This effectively sets the alpha component of the view's tint color.
    */
    void setOpacity(double opacity)  { setTintColor(_tintColor.withAlphaF(opacity)); }
    double opacity() const           { return _tintColor.alphaF(); }

    /**
    * Returns true if the view's ancestors are visible or if the view has no ancestors.
    */
    bool ancestorsAreVisible() const;

    /**
    * Returns true if the view and its ancestors are visible and in an open window.
    */
    bool isVisibleInOpenWindow() const;

    /**
    * Arranges the view so it's behind all of its current siblings.
    */
    void sendToBack();

    /**
    * Arranges the view so it's in front of all of its current siblings.
    */
    void bringToFront();

    /**
    * Override this if the view can become focused.
    */
    virtual bool canBecomeDirectFocus() { return false; }

    /**
    * Makes the view the current focus. If the view has a preferred focus, the preferred focus will
    * become the focus instead.
    */
    void focus();

    /**
    * Returns the view that would become focused if an attempt to give focus to this view is made.
    */
    View* expectedFocus();

    /**
    * Sets the focus to the next ancestor that can be focused which doesn't result in this view
    * retaining focus (which would otherwise happen if your ancestor's preferred focus was you)
    */
    void focusAncestor();

    /**
    * If the view or any of its children are focused, unfocuses them.
    */
    void unfocus();

    /**
    * If this view would receive focus and has a preferred focus, the preferred focus will become focus instead.
    */
    View* preferredFocus() const       { return _preferredFocus; }
    void setPreferredFocus(View* view) { _preferredFocus = view; }

    View* nextFocus() const     { return _nextFocus; }
    View* previousFocus() const { return _previousFocus; }

    /**
    * If the view receives an unhandled tab key down, focus will change to the given
    * view (and shift+tab will do the opposite).
    */
    void setNextFocus(View* view);

    /**
    * Returns the next available visible and focusable view if there is one.
    */
    View* nextAvailableFocus();

    /**
    * Returns the previous available visible and focusable view.
    */
    View* previousAvailableFocus();

    /**
    * Returns true if the view or any of its children has focus.
    */
    bool isFocus() const;

    TouchpadFocus& touchpadFocus() { return _touchpadFocus; }

    /**
    * @param rendersToTexture if true, the view is rendered to a texture, making it available via renderTexture
    */
    void setRendersToTexture(bool rendersToTexture = true) { _rendersToTexture = rendersToTexture; }

    /**
    * If the view is set to render to a texture, this can be used to obtain said texture.
    */
    std::shared_ptr<TextureInterface> renderTexture() const;

    /**
    * @param caches if true, the view will render to a texture and the render() method will only be called when
    *               the cache is invalid
    */
    void setCachesRender(bool cachesRender = true) { _cachesRender = cachesRender; }

    /**
    * Invalidates the view's render cache.
    */
    void invalidateRenderCache();

    /**
    * @param clipsToBounds if true, the view will not render itself or any subviews outside of its bounds
    */
    void setClipsToBounds(bool clipsToBounds = true) { _clipsToBounds = clipsToBounds; }

    /**
    * @return if true, the view will not render itself or any subviews outside of its bounds
    */
    bool clipsToBounds() const { return _clipsToBounds; }

    /**
    * Returns true if the mouse is hovering directly over this view.
    */
    bool hasMouse() const;

    shaders::ColorShader* colorShader() { return shader<shaders::ColorShader>("color shader"); }
    shaders::TextureShader* textureShader() { return shader<shaders::TextureShader>("texture shader"); }
    shaders::DistanceFieldShader* distanceFieldShader() { return shader<shaders::DistanceFieldShader>("distance field shader"); }

    /**
    * Begins loading a texture associated with the view. When the texture is loaded, the view's
    * render cache will be invalidated. If the texture should not be associated with the view,
    * use Window::loadTexture* instead.
    */
    TextureHandle loadTextureResource(const std::string& name);
    TextureHandle loadTextureFromMemory(std::shared_ptr<const std::string> data);
    TextureHandle loadTextureFromURL(const std::string& url);

    /**
    * Get or create a shader cached via the window's shader cache.
    */
    template <typename T>
    T* shader(const char* identifier);

    const AffineTransformation& renderTransformation() const { return _renderTransformation; }

    /**
    * Converts a point from local coordinates to superview coordinates.
    */
    Point<double> localToSuperview(double x, double y) const { return localToAncestor(x, y, superview()); }
    Point<double> localToSuperview(const Point<double>& p) const { return localToSuperview(p.x, p.y); }

    /**
    * Converts a point from local coordinates to the coordinates of an ancestor.
    */
    Point<double> localToAncestor(double x, double y, const View* ancestor) const;
    Point<double> localToAncestor(const Point<double>& p, const View* ancestor) const { return localToAncestor(p.x, p.y, ancestor); }

    /**
    * Converts a point from super coordinates to local coordinates.
    */
    Point<double> superviewToLocal(double x, double y) const;
    Point<double> superviewToLocal(const Point<double>& p) const;

    /**
    * Converts a point from local coordinates to window coordinates.
    */
    Point<double> localToWindow(double x, double y) const;
    Point<double> localToWindow(const Point<double>& p) const;

    /**
    * Returns true if this view has the given relation to the given view.
    *
    * For example, hasRelation(kDescendant, superview()) should return true.
    */
    bool hasRelation(Relation relation, const View* view) const;

    /**
    * Returns the first view that both views have in their hierarchy, if any.
    */
    const View* commonView(const View* other) const { return commonNode(other); }

    using TreeNode::isDescendantOf;
    using TreeNode::isAncestorOf;

    /**
    * Posts a message to listeners with the given relation. The view and its potential listeners must have an
    * associated application for the message to be delivered.
    *
    * For example, post(message, Relation::kAncestor) posts the message to listeners that are ancestors of this view.
    */
    template <typename T>
    void post(T& message, Relation relation = Relation::kHierarchy) {
        _post(std::type_index(typeid(typename std::decay_t<T>)), &message, relation);
    }
    template <typename T>
    void post(T&& message, Relation relation = Relation::kHierarchy) {
        T m = std::move(message);
        _post(std::type_index(typeid(typename std::decay_t<T>)), &m, relation);
    }

    template <typename T>
    struct ListenerAction : ListenerAction<decltype(&T::operator())> {};

    template <typename C, typename R, typename... Args>
    struct ListenerAction<R(C::*)(Args...) const> {
        using ArgumentTuple = std::tuple<Args...>;
        using ArgumentCount = std::tuple_size<ArgumentTuple>;
        using MessageType = typename std::decay<typename std::tuple_element<0, ArgumentTuple>::type>::type;
    };

    /**
    * Listens for messages from senders with the given relation.
    *
    * For example, listen([](const Message& message) {}, Relation::kAncestor) listens for messages from posters that
    * are ancestors of this view.
    *
    * @param action an action that takes a constant reference to the message type to listen for and optionally a View pointer to the sender
    */
    template <typename Action>
    auto listen(Action&& action, Relation relation = Relation::kHierarchy) -> typename std::enable_if<ListenerAction<Action>::ArgumentCount::value == 1, void>::type {
        using MessageType = typename ListenerAction<Action>::MessageType;
        _listen(std::type_index(typeid(MessageType)),
            [action = std::forward<Action>(action)](const void* message, View* sender) {
                action(*reinterpret_cast<const MessageType*>(message));
            }, relation
        );
    }

    template <typename Action>
    auto listen(Action&& action, Relation relation = Relation::kHierarchy) -> typename std::enable_if<ListenerAction<Action>::ArgumentCount::value == 2, void>::type {
        using MessageType = typename ListenerAction<Action>::MessageType;
        _listen(std::type_index(typeid(MessageType)),
            [action = std::forward<Action>(action)](const void* message, View* sender) {
                action(*reinterpret_cast<const MessageType*>(message), sender);
            }, relation
        );
    }

    /**
    * Makes the given object available via get(). This can be used to store arbitrary state with the view.
    *
    * @param relation the object will only be available to views of the given relation
    */
    template <typename T>
    auto set(T&& object, Relation relation = Relation::kHierarchy) {
        _provisions.emplace_front(std::forward<T>(object), relation);
        return stdts::any_cast<std::decay_t<T>>(&_provisions.front().object);
    }

    /**
    * Finds an object provided via provide. It will return a pointer to the first object it finds of the
    * specified type. If more than one objects of the given type has been provided, it is undefined
    * which one will be returned.
    *
    * @param relation only objects from views of the given relation will be returned
    */
    template <typename T>
    T* find(Relation relation = Relation::kHierarchy);

    template <typename T>
    T* get() { return find<T>(Relation::kSelf); }

    template <typename T>
    T* inherit() { return find<T>(Relation::kAncestor); }

    /**
    * Asynchronously schedules a function to be invoked using the application's task scheduler.
    *
    * If the view is destroyed, the invocation will be canceled.
    */
    template <typename... Args>
    auto async(Args&&... args) -> decltype(std::declval<scraps::AbstractTaskScheduler>().async(std::forward<Args>(args)...)) {
        return _taskScheduler()->async(_taskScope, std::forward<Args>(args)...);
    }

    /**
    * Asynchronously schedules a function to be invoked after a delay using the application's task scheduler.
    *
    * If the view is destroyed, the invocation will be canceled.
    */
    template <typename... Args>
    auto asyncAfter(Args&&... args) -> decltype(std::declval<scraps::AbstractTaskScheduler>().asyncAfter(std::forward<Args>(args)...)) {
        return _taskScheduler()->asyncAfter(_taskScope, std::forward<Args>(args)...);
    }

    /**
    * Asynchronously schedules a function to be invoked at a time using the application's task scheduler.
    *
    * If the view is destroyed, the invocation will be canceled.
    */
    template <typename... Args>
    auto asyncAt(Args&&... args) -> decltype(std::declval<scraps::AbstractTaskScheduler>().asyncAt(std::forward<Args>(args)...)) {
        return _taskScheduler()->asyncAt(_taskScope, std::forward<Args>(args)...);
    }

    /**
    * The hook provided here will be called before rendering each frame.
    */
    void addUpdateHook(const std::string& handle, std::function<void()> hook);

    /**
    * The hook provided here will no longer be called.
    */
    void removeUpdateHook(const std::string& handle);

    /**
    * Override this to do drawing.
    */
    virtual void render() {}

    virtual void render(const RenderTarget* renderTarget, const Rectangle<int>& area) { render(); }

    /**
    * Override this to implement custom post-render effects. For this method to be called, the view must be
    * set to render to texture. The default implementation provides the built-in effects such as tint and
    * opacity. If this is overridden, you will need to provide those effects in your implementation in
    * order to use them.
    *
    * @param texture the view, rendered to a texture with premultiplied alpha
    */
    virtual void postRender(std::shared_ptr<TextureInterface> texture, const AffineTransformation& transformation);

    /**
    * Override this to lay out subviews whenever the view is resized.
    */
    virtual void layout() {}

    /**
    * Override this to do any sort of setup that requires the view to be attached to a window.
    */
    virtual void windowChanged() {}

    /**
    * Override this if you want odd-shaped views to have accurate hit boxes.
    */
    virtual bool hitTest(double x, double y);
    bool hitTest(const Point<double>& p) { return hitTest(p.x, p.y); }

    /**
    * Return the most descendant visible view which intersects with (x, y)
    */
    View* hitTestView(double x, double y);
    View* hitTestView(const Point<double>& p) { return hitTestView(p.x, p.y); }

    /**
    * Override these to handle mouse events. Call the base implementation to pass on the event.
    */
    virtual void mouseDown(MouseButton button, double x, double y);
    virtual void mouseUp(MouseButton button, double startX, double startY, double x, double y);
    virtual void mouseWheel(double xPos, double yPos, int xWheel, int yWheel);
    virtual void mouseDrag(double startX, double startY, double x, double y);
    virtual void mouseMovement(double x, double y);
    virtual void mouseEnter() {}
    virtual void mouseExit() {}

    /**
    * Called whenever the view or one of its subviews gains focus.
    */
    virtual void focusGained() {}

    /**
    * Called whenever the view and its subviews lose focus.
    */
    virtual void focusLost() {}

    /**
    * Called whenever the view or any subview gains or loses focus.
    */
    virtual void focusChanged() {}

    /**
    * Called before the view and all of its ancestors become visible in the window.
    */
    virtual void willAppear() {}

    /**
    * Called when the view and all of its ancestors become visible in the window.
    */
    virtual void appeared() {}

    /**
    * Called before the view or one of its ancestors become invisible in the window.
    */
    virtual void willDisappear() {}

    /**
    * Called when the view or one of its ancestors become invisible in the window.
    */
    virtual void disappeared() {}

    /**
    * Renders the view and its subviews.
    *
    * @param area the area within the target to render to. the view will fill this area
    * @param clipBounds the bounds within the target to clip rendering of the view and its children to
    */
    void renderAndRenderSubviews(const RenderTarget* target, const Rectangle<int>& area, stdts::optional<Rectangle<int>> clipBounds = stdts::nullopt);

    bool dispatchMouseDown(MouseButton button, double x, double y);
    bool dispatchMouseUp(MouseButton button, double startX, double startY, double x, double y);
    bool dispatchMouseMovement(double x, double y);
    bool dispatchMouseWheel(double xPos, double yPos, int xWheel, int yWheel);
    void dispatchUpdate(std::chrono::high_resolution_clock::duration elapsed);

    // Responder overrides
    virtual Responder* nextResponder() override;
    virtual void keyDown(KeyCode key, KeyModifiers mod, bool repeat) override;
    virtual void touchUp(size_t finger, Point<double> position, double pressure) override;
    virtual void touchDown(size_t finger, Point<double> position, double pressure) override;
    virtual void touchMovement(size_t finger, Point<double> position, Point<double> distance, double pressure) override;

private:
    friend class scraps::TreeNode<View>;
    friend class Window;

    struct Listener {
        Listener(std::type_index index, std::function<void(const void*, View*)> action, Relation relation)
            : index{index}, action{std::move(action)}, relation{relation} {}

        std::type_index index;
        std::function<void(const void*, View*)> action;
        Relation relation;
    };

    struct Provision {
        Provision(stdts::any object, Relation relation)
            : object{std::move(object)}, relation{relation} {}

        stdts::any object;
        Relation relation;
    };

    void _addSubviews() {}
    template <typename... Views>
    void _addSubviews(View* view, Views&&... views);

    void _removeSubviews() {}
    template <typename... Views>
    void _removeSubviews(View* view, Views&&... views);

    void _setBounds(const Rectangle<double>& bounds);

    void _invalidateSuperviewRenderCache();

    void _dispatchFutureVisibilityChange(bool visible);
    void _dispatchVisibilityChange(bool visible);
    void _dispatchWindowChange(Window* window);
    void _mouseExit();

    void _updateFocusableRegions(std::vector<std::tuple<View*, Rectangle<double>>>& regions);

    bool _requiresTextureRendering();
    void _renderAndRenderSubviews(const RenderTarget* target, const Rectangle<int>& area, bool shouldClear = false, stdts::optional<Rectangle<int>> clipBounds = stdts::nullopt);

    void _post(std::type_index index, const void* ptr, Relation relation);
    void _listen(std::type_index index, std::function<void(const void*, View*)> action, Relation relation);

    template <typename F>
    void _traverseRelation(Relation relation, F&& function);

    std::vector<View*> _topViewsForRelation(Relation relation);

    scraps::AbstractTaskScheduler* _taskScheduler() const;
    void _updateTouchFocus(std::chrono::high_resolution_clock::duration elapsed);

    void _checkUpdateSubscription();
    bool _shouldSubscribeToUpdates();

    std::string _name;
    bool _isVisible                     = true;
    bool _rendersToTexture              = false;
    bool _cachesRender                  = false;
    bool _hasCachedRender               = false;
    bool _clipsToBounds                 = true;
    bool _interceptsInteractions        = true;
    bool _childrenInterceptInteractions = true;

    Window* _window                     = nullptr;
    View*   _subviewWithMouse           = nullptr;
    View*   _nextFocus                  = nullptr;
    View*   _previousFocus              = nullptr;
    View*   _preferredFocus             = nullptr;

    Rectangle<double>    _bounds;
    Point<double>        _scale{1.0, 1.0};
    Color                _backgroundColor = Color::kTransparentBlack;
    Color                _tintColor = Color::kWhite;
    AffineTransformation _renderTransformation;

    std::unique_ptr<opengl::Framebuffer> _renderCache;
    opengl::Framebuffer::Attachment*     _renderCacheColorAttachment = nullptr;
    std::shared_ptr<WeakTexture>         _renderCacheTexture = std::make_shared<WeakTexture>();

    std::list<Listener>                               _listeners;
    std::list<Provision>                              _provisions;
    TouchpadFocus                                     _touchpadFocus;
    std::unordered_map<size_t, std::function<void()>> _updateHooks;

    scraps::AbstractTaskScheduler::TaskScope          _taskScope; /* must be the last member */
};

template <typename... Views>
void View::_addSubviews(View* view, Views&&... views) {
    addSubview(view);
    _addSubviews(std::forward<Views>(views)...);
}

template <typename... Views>
void View::_removeSubviews(View* view, Views&&... views) {
    removeSubview(view);
    _removeSubviews(std::forward<Views>(views)...);
}

template <typename T>
T* View::shader(const char* identifier) {
    auto s = shaderCache()->get(std::string(identifier));
    if (!s) {
        s = shaderCache()->add(std::make_unique<T>(), std::string(identifier), ShaderCache::Policy::kKeepForever);
    }
    auto ret = dynamic_cast<T*>(s->get());
    ret->setTransformation(renderTransformation());
    return ret;
}

template <typename T>
T* View::find(Relation relation) {
    T* ret = nullptr;
    _traverseRelation(relation, [&](View* view, bool* shouldContinue) {
        for (auto& provision : view->_provisions) {
            if (!hasRelation(provision.relation, view)) { continue; }
            if (auto object = stdts::any_cast<T>(&provision.object)) {
                ret = object;
                *shouldContinue = false;
                return 1;
            }
            if (auto pointer = stdts::any_cast<T*>(&provision.object)) {
                ret = *pointer;
                *shouldContinue = false;
                return 1;
            }
        }
        return 0;
    });
    if (!ret && application() && (relation == Relation::kHierarchy || relation == Relation::kAny || relation == Relation::kAncestor)) {
        return application()->get<T>();
    }
    return ret;
}

template <typename F>
void View::_traverseRelation(Relation relation, F&& function) {
    switch (relation) {
        case Relation::kAny: {
            bool shouldContinue = true;
            for (auto& v : _topViewsForRelation(relation)) {
                v->TreeNode::traverseRelation(TreeNode::Relation::kCommonRoot, function, 0, &shouldContinue);
            }
            break;
        }
        case Relation::kHierarchy:  TreeNode::traverseRelation(TreeNode::Relation::kCommonRoot, function, 0); break;
        case Relation::kDescendant: TreeNode::traverseRelation(TreeNode::Relation::kDescendant, function, 0); break;
        case Relation::kAncestor:   TreeNode::traverseRelation(TreeNode::Relation::kAncestor,   function, 0); break;
        case Relation::kSibling:    TreeNode::traverseRelation(TreeNode::Relation::kSibling,    function, 0); break;
        case Relation::kSelf:       TreeNode::traverseRelation(TreeNode::Relation::kSelf,       function, 0); break;
    }
}

} // namespace okui

max_stars_repo_name: bittorrent/okui

max_issues_repo_name: bittorrent/okui

max_forks_repo_name: bittorrent/okui


text:
/*
 * Copyright (c) 2016-2021 lymastee, All rights reserved.
 * Contact: lymastee@hotmail.com
 *
 * This file is part of the gslib project.
 *
 * 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.
 */

#pragma once

#ifndef config_27ec2780_3d0a_41f9_8a8b_0099ced77cf1_h
#define config_27ec2780_3d0a_41f9_8a8b_0099ced77cf1_h

#include <gslib/config.h>

#define __ariel_begin__     namespace gs { namespace ariel {
#define __ariel_end__       } };

#if defined(ARIEL_LIB)
#define ariel_export
#elif defined(ARIEL_DLL)
#define ariel_export __declspec(dllexport)
#else
#define ariel_export __declspec(dllimport)
#endif

enum
{
    render_platform_gl_20,
    render_platform_gl_30,
    render_platform_d3d_9,
    render_platform_d3d_11,
};

/* select render system here. */
#define select_render_platform  render_platform_d3d_11

#define use_rendersys_d3d_9     (select_render_platform == render_platform_d3d_9)
#define use_rendersys_d3d_11    (select_render_platform == render_platform_d3d_11)
#define use_rendersys_gl_20     (select_render_platform == render_platform_gl_20)
#define use_rendersys_gl_30     (select_render_platform == render_platform_gl_30)

#if use_rendersys_d3d_11
#include <d3d11.h>
#include <dxgi.h>
#endif

__ariel_begin__

define_select_type(render_device);
define_select_type(render_context);
define_select_type(render_resource);
define_select_type(render_swap_chain);
define_select_type(render_target_view);
define_select_type(shader_resource_view);
define_select_type(depth_stencil_view);
define_select_type(unordered_access_view);
define_select_type(render_blob);
define_select_type(vertex_shader);
define_select_type(pixel_shader);
define_select_type(geometry_shader);
define_select_type(compute_shader);
define_select_type(hull_shader);
define_select_type(domain_shader);
define_select_type(render_include);
define_select_type(vertex_format);
define_select_type(vertex_format_desc);
define_select_type(render_vertex_buffer);
define_select_type(render_index_buffer);
define_select_type(render_constant_buffer);
define_select_type(render_texture1d);
define_select_type(render_texture2d);
define_select_type(render_texture3d);
define_select_type(render_sampler_state);
define_select_type(render_blend_state);
define_select_type(render_raster_state);
define_select_type(render_depth_state);

install_select_type(render_platform_d3d_11, render_device, ID3D11Device);
install_select_type(render_platform_d3d_11, render_context, ID3D11DeviceContext);
install_select_type(render_platform_d3d_11, render_resource, ID3D11Resource);
install_select_type(render_platform_d3d_11, render_swap_chain, IDXGISwapChain);
install_select_type(render_platform_d3d_11, render_target_view, ID3D11RenderTargetView);
install_select_type(render_platform_d3d_11, shader_resource_view, ID3D11ShaderResourceView);
install_select_type(render_platform_d3d_11, depth_stencil_view, ID3D11DepthStencilView);
install_select_type(render_platform_d3d_11, unordered_access_view, ID3D11UnorderedAccessView);
install_select_type(render_platform_d3d_11, render_blob, ID3DBlob);
install_select_type(render_platform_d3d_11, vertex_shader, ID3D11VertexShader);
install_select_type(render_platform_d3d_11, pixel_shader, ID3D11PixelShader);
install_select_type(render_platform_d3d_11, geometry_shader, ID3D11GeometryShader);
install_select_type(render_platform_d3d_11, compute_shader, ID3D11ComputeShader);
install_select_type(render_platform_d3d_11, hull_shader, ID3D11HullShader);
install_select_type(render_platform_d3d_11, domain_shader, ID3D11DomainShader);

install_select_type(render_platform_d3d_11, render_include, ID3DInclude);
install_select_type(render_platform_d3d_11, vertex_format, ID3D11InputLayout);
install_select_type(render_platform_d3d_11, vertex_format_desc, D3D11_INPUT_ELEMENT_DESC);
install_select_type(render_platform_d3d_11, render_vertex_buffer, ID3D11Buffer);
install_select_type(render_platform_d3d_11, render_index_buffer, ID3D11Buffer);
install_select_type(render_platform_d3d_11, render_constant_buffer, ID3D11Buffer);

install_select_type(render_platform_d3d_11, render_texture1d, ID3D11Texture1D);
install_select_type(render_platform_d3d_11, render_texture2d, ID3D11Texture2D);
install_select_type(render_platform_d3d_11, render_texture3d, ID3D11Texture3D);
install_select_type(render_platform_d3d_11, render_sampler_state, ID3D11SamplerState);
install_select_type(render_platform_d3d_11, render_blend_state, ID3D11BlendState);
install_select_type(render_platform_d3d_11, render_raster_state, ID3D11RasterizerState);
install_select_type(render_platform_d3d_11, render_depth_state, ID3D11DepthStencilState);

config_select_type(select_render_platform, render_device);
config_select_type(select_render_platform, render_context);
config_select_type(select_render_platform, render_resource);
config_select_type(select_render_platform, render_swap_chain);
config_select_type(select_render_platform, render_target_view);
config_select_type(select_render_platform, shader_resource_view);
config_select_type(select_render_platform, depth_stencil_view);
config_select_type(select_render_platform, unordered_access_view);
config_select_type(select_render_platform, render_blob);
config_select_type(select_render_platform, vertex_shader);
config_select_type(select_render_platform, pixel_shader);
config_select_type(select_render_platform, geometry_shader);
config_select_type(select_render_platform, compute_shader);
config_select_type(select_render_platform, hull_shader);
config_select_type(select_render_platform, domain_shader);
config_select_type(select_render_platform, render_include);
config_select_type(select_render_platform, vertex_format);
config_select_type(select_render_platform, render_vertex_buffer);
config_select_type(select_render_platform, render_index_buffer);
config_select_type(select_render_platform, render_constant_buffer);
config_select_type(select_render_platform, render_texture1d);
config_select_type(select_render_platform, render_texture2d);
config_select_type(select_render_platform, render_texture3d);
config_select_type(select_render_platform, render_sampler_state);
config_select_type(select_render_platform, render_blend_state);
config_select_type(select_render_platform, render_raster_state);
config_select_type(select_render_platform, render_depth_state);

enum render_option
{
    opt_primitive_topology,
    /* more to come. */
};

__ariel_end__

#endif

ext: h

max_stars_repo_name: lymastee/gslib

max_issues_repo_name: lymastee/gslib

max_forks_repo_name: lymastee/gslib


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include "core/common/logging/logging.h"
#include "core/framework/allocatormgr.h"
#include "core/framework/customregistry.h"
#include "core/framework/execution_frame.h"
#include "core/framework/op_kernel.h"
#include "core/framework/run_options.h"
#include "core/framework/session_state.h"
#include "core/framework/tensor.h"
#include "core/graph/graph_viewer.h"
#include "core/graph/model.h"
#include "core/framework/data_types.h"
#include "test/test_environment.h"
#include "test/framework/TestAllocatorManager.h"
#include "core/framework/TensorSeq.h"
#include "core/framework/session_options.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <gsl/gsl>
#include "core/util/math_cpuonly.h"

// helpers to run a function and check the status, outputting any error if it fails.
// note: wrapped in do{} while(false) so the _tmp_status variable has limited scope
#define ASSERT_STATUS_OK(function)                  \
  do {                                              \
    auto _tmp_status = function;                    \
    ASSERT_TRUE(_tmp_status.IsOK()) << _tmp_status; \
  } while (false)

#define EXPECT_STATUS_OK(function)                  \
  do {                                              \
    auto _tmp_status = function;                    \
    EXPECT_TRUE(_tmp_status.IsOK()) << _tmp_status; \
  } while (false)

namespace onnxruntime {
class InferenceSession;
struct SessionOptions;

namespace test {
template <typename T>
struct SeqTensors {
  void AddTensor(const std::vector<int64_t>& shape0, const std::vector<T>& data0) {
    tensors.push_back(Tensor<T>{shape0, data0});
  }

  template <typename U>
  struct Tensor {
    std::vector<int64_t> shape;
    std::vector<U> data;
  };
  std::vector<Tensor<T>> tensors;
};

// unfortunately std::optional is in C++17 so use a miniversion of it
template <typename T>
class optional {
 public:
  optional(T v) : has_value_(true), value_(v) {}
  optional() : has_value_(false) {}
  bool has_value() const { return has_value_; }
  const T& value() const {
    ORT_ENFORCE(has_value_);
    return value_;
  }

 private:
  bool has_value_;
  T value_;
};

// Function templates to translate C++ types into ONNX_NAMESPACE::TensorProto_DataTypes
template <typename T>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType();

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<float>() {
  return ONNX_NAMESPACE::TensorProto_DataType_FLOAT;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<double>() {
  return ONNX_NAMESPACE::TensorProto_DataType_DOUBLE;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<int32_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_INT32;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<int64_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_INT64;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<bool>() {
  return ONNX_NAMESPACE::TensorProto_DataType_BOOL;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<int8_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_INT8;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<int16_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_INT16;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<uint8_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_UINT8;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<uint16_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_UINT16;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<uint32_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_UINT32;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<uint64_t>() {
  return ONNX_NAMESPACE::TensorProto_DataType_UINT64;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<std::string>() {
  return ONNX_NAMESPACE::TensorProto_DataType_STRING;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<MLFloat16>() {
  return ONNX_NAMESPACE::TensorProto_DataType_FLOAT16;
}

template <>
constexpr ONNX_NAMESPACE::TensorProto_DataType TypeToDataType<BFloat16>() {
  return ONNX_NAMESPACE::TensorProto_DataType_BFLOAT16;
}

template <typename T>
struct TTypeProto : ONNX_NAMESPACE::TypeProto {
  TTypeProto(const std::vector<int64_t>* shape = nullptr) {
    mutable_tensor_type()->set_elem_type(TypeToDataType<T>());

    if (shape) {
      auto mutable_shape = mutable_tensor_type()->mutable_shape();
      for (auto i : *shape) {
        auto* mutable_dim = mutable_shape->add_dim();
        if (i != -1)
          mutable_dim->set_dim_value(i);
        else
          mutable_dim->set_dim_param("symbolic");
      }
    }
  }
};

// Variable template for ONNX_NAMESPACE::TensorProto_DataTypes, s_type_proto<float>, etc..
template <typename T>
struct TTensorType {
  static const TTypeProto<T> s_type_proto;
};

template <typename T>
const TTypeProto<T> TTensorType<T>::s_type_proto;

// TypeProto for map<TKey, TVal>
template <typename TKey, typename TVal>
struct MTypeProto : ONNX_NAMESPACE::TypeProto {
  MTypeProto() {
    mutable_map_type()->set_key_type(TypeToDataType<TKey>());
    mutable_map_type()->mutable_value_type()->mutable_tensor_type()->set_elem_type(TypeToDataType<TVal>());
    mutable_map_type()->mutable_value_type()->mutable_tensor_type()->mutable_shape()->clear_dim();
  }
};

template <typename TKey, typename TVal>
struct MMapType {
  static const MTypeProto<TKey, TVal> s_map_type_proto;
};

template <typename TKey, typename TVal>
const MTypeProto<TKey, TVal> MMapType<TKey, TVal>::s_map_type_proto;

// TypeProto for vector<map<TKey, TVal>>
template <typename TKey, typename TVal>
struct VectorOfMapTypeProto : ONNX_NAMESPACE::TypeProto {
  VectorOfMapTypeProto() {
    auto* map_type = mutable_sequence_type()->mutable_elem_type()->mutable_map_type();
    map_type->set_key_type(TypeToDataType<TKey>());
    map_type->mutable_value_type()->mutable_tensor_type()->set_elem_type(TypeToDataType<TVal>());
    map_type->mutable_value_type()->mutable_tensor_type()->mutable_shape()->clear_dim();
  }
};

template <typename TKey, typename TVal>
struct VectorOfMapType {
  static const VectorOfMapTypeProto<TKey, TVal> s_vec_map_type_proto;
};

template <typename TKey, typename TVal>
const VectorOfMapTypeProto<TKey, TVal> VectorOfMapType<TKey, TVal>::s_vec_map_type_proto;

template <typename ElemType>
struct SequenceTensorTypeProto : ONNX_NAMESPACE::TypeProto {
  SequenceTensorTypeProto() {
    MLDataType dt = DataTypeImpl::GetTensorType<ElemType>();
    const auto* elem_proto = dt->GetTypeProto();
    mutable_sequence_type()->mutable_elem_type()->CopyFrom(*elem_proto);
    auto* tensor_type = mutable_sequence_type()->mutable_elem_type()->mutable_tensor_type();
    tensor_type->set_elem_type(TypeToDataType<ElemType>());
  }
};

template <typename ElemType>
struct SequenceTensorType {
  static const SequenceTensorTypeProto<ElemType> s_sequence_tensor_type_proto;
};

template <typename ElemType>
const SequenceTensorTypeProto<ElemType> SequenceTensorType<ElemType>::s_sequence_tensor_type_proto;

// To use OpTester:
//  1. Create one with the op name
//  2. Call AddAttribute with any attributes
//  3. Call AddInput for all the inputs
//  4. Call AddOutput with all expected outputs
//  5. Call Run
// Not all tensor types and output types are added, if a new input type is used, add it to the TypeToDataType list
// above for new output types, add a new specialization for Check<> See current usage for an example, should be self
// explanatory
class OpTester {
 public:
  // Default to the first opset that ORT was available (7).
  // When operators are updated they need to explicitly add tests for the new opset version.
  // This is due to the kernel matching logic. See KernelRegistry::VerifyKernelDef.
  // Additionally, -1 is supported and defaults to the latest known opset.
  //
  // Defaulting to the latest opset version would result in existing operator implementations for non-CPU EPs to
  // lose their test coverage until an implementation for the new version is added.
  //   e.g. there are CPU and GPU implementations for version 1 of an op. both are tested by a single OpTester test.
  //        opset changes from 1 to 2 and CPU implementation gets added. If 'opset_version' is 2 the kernel matching
  //        will find and run the CPU v2 implementation, but will not match the GPU v1 implementation.
  //        OpTester will say it was successful as at least one EP ran, and the GPU implementation of v1 no longer has
  //        test coverage.
  explicit OpTester(const char* op, int opset_version = 7, const char* domain = onnxruntime::kOnnxDomain)
      : op_(op), domain_(domain), opset_version_(opset_version) {
    if (opset_version_ < 0) {
      static int latest_onnx_version =
          ONNX_NAMESPACE::OpSchemaRegistry::DomainToVersionRange().Map().at(ONNX_NAMESPACE::ONNX_DOMAIN).second;
      opset_version_ = latest_onnx_version;
    }
  }

  ~OpTester();

  // Set whether the NodeArg created by AddInput/AddOutput should include shape information
  // for Tensor types. If not added, shape inferencing should resolve. If added, shape inferencing
  // should validate. Default is to not add.
  // Additionally a symbolic dimension will be added if symbolic_dim matches a dimension in the input.
  OpTester& AddShapeToTensorData(bool add_shape = true, int symbolic_dim = -1) {
    add_shape_to_tensor_data_ = add_shape;
    add_symbolic_dim_to_tensor_data_ = symbolic_dim;
    return *this;
  }

  // We have an initializer_list and vector version of the Add functions because std::vector is specialized for
  // bool and we can't get the raw data out. So those cases must use an initializer_list
  template <typename T>
  void AddInput(const char* name, const std::vector<int64_t>& dims, const std::initializer_list<T>& values,
                bool is_initializer = false) {
    AddData(input_data_, name, dims, values.begin(), values.size(), is_initializer);
  }

  template <typename T>
  void AddInput(const char* name, const std::vector<int64_t>& dims, const std::vector<T>& values,
                bool is_initializer = false) {
    AddData(input_data_, name, dims, values.data(), values.size(), is_initializer);
  }

  // Add other registered types, possibly experimental
  template <typename T>
  void AddInput(const char* name, const T& val) {
    auto mltype = DataTypeImpl::GetType<T>();
    ORT_ENFORCE(mltype != nullptr, "T must be a registered cpp type");
    auto ptr = onnxruntime::make_unique<T>(val);
    OrtValue value;
    value.Init(ptr.get(), mltype, mltype->GetDeleteFunc());
    ptr.release();
    input_data_.push_back(Data(NodeArg(name, mltype->GetTypeProto()), std::move(value), optional<float>(),
                               optional<float>()));
  }

  template <typename T>
  void AddInput(const char* name, T&& val) {
    auto mltype = DataTypeImpl::GetType<T>();
    ORT_ENFORCE(mltype != nullptr, "T must be a registered cpp type");
    auto ptr = onnxruntime::make_unique<T>(std::move(val));
    OrtValue value;
    value.Init(ptr.get(), mltype, mltype->GetDeleteFunc());
    ptr.release();
    input_data_.push_back(Data(NodeArg(name, mltype->GetTypeProto()), std::move(value), optional<float>(),
                               optional<float>()));
  }

  template <typename T>
  void AddSeqInput(const char* name, const SeqTensors<T>& seq_tensors) {
    AddSeqData<T>(input_data_, name, seq_tensors);
  }

  template <typename T>
  void AddSeqOutput(const char* name, const SeqTensors<T>& seq_tensors) {
    AddSeqData<T>(output_data_, name, seq_tensors);
  }

  template <typename TKey, typename TVal>
  void AddInput(const char* name, const std::map<TKey, TVal>& val) {
    std::unique_ptr<std::map<TKey, TVal>> ptr = onnxruntime::make_unique<std::map<TKey, TVal>>(val);
    OrtValue value;
    value.Init(ptr.release(), DataTypeImpl::GetType<std::map<TKey, TVal>>(),
               DataTypeImpl::GetType<std::map<TKey, TVal>>()->GetDeleteFunc());
    input_data_.push_back(Data(NodeArg(name, &MMapType<TKey, TVal>::s_map_type_proto), std::move(value),
                               optional<float>(), optional<float>()));
  }

  template <typename T>
  void AddMissingOptionalInput() {
    std::string name;  // empty == input doesn't exist
    input_data_.push_back(Data(NodeArg(name, &TTensorType<T>::s_type_proto), OrtValue(), optional<float>(),
                               optional<float>()));
  }

  template <typename T>
  void AddOutput(const char* name, const std::vector<int64_t>& dims, const std::initializer_list<T>& expected_values,
                 bool sort_output = false) {
    AddData(output_data_, name, dims, expected_values.begin(), expected_values.size(), false, sort_output);
  }

  template <typename T>
  void AddOutput(const char* name, const std::vector<int64_t>& dims, const std::vector<T>& expected_values,
                 bool sort_output = false) {
    AddData(output_data_, name, dims, expected_values.data(), expected_values.size(), false, sort_output);
  }

  template <typename T>
  void AddMissingOptionalOutput() {
    std::string name;  // empty == input doesn't exist
    output_data_.push_back(Data(NodeArg(name, &TTensorType<T>::s_type_proto), OrtValue(), optional<float>(),
                                optional<float>()));
  }

  // Add other registered types, possibly experimental
  template <typename T>
  void AddOutput(const char* name, const T& val) {
    auto mltype = DataTypeImpl::GetType<T>();
    ORT_ENFORCE(mltype != nullptr, "T must be a registered cpp type");
    auto ptr = onnxruntime::make_unique<T>(val);
    OrtValue value;
    value.Init(ptr.get(), mltype, mltype->GetDeleteFunc());
    ptr.release();
    output_data_.push_back(Data(NodeArg(name, mltype->GetTypeProto()), std::move(value), optional<float>(),
                                optional<float>()));
  }

  template <typename T>
  void AddOutput(const char* name, T&& val) {
    auto mltype = DataTypeImpl::GetType<T>();
    ORT_ENFORCE(mltype != nullptr, "T must be a registered cpp type");
    auto ptr = onnxruntime::make_unique<T>(std::move(val));
    OrtValue value;
    value.Init(ptr.get(), mltype, mltype->GetDeleteFunc());
    ptr.release();
    output_data_.push_back(Data(NodeArg(name, mltype->GetTypeProto()), std::move(value), optional<float>(),
                                optional<float>()));
  }

  // Add non tensor output
  template <typename TKey, typename TVal>
  void AddOutput(const char* name, const std::vector<std::map<TKey, TVal>>& val) {
    auto ptr = onnxruntime::make_unique<std::vector<std::map<TKey, TVal>>>(val);
    OrtValue ml_value;
    ml_value.Init(ptr.release(), DataTypeImpl::GetType<std::vector<std::map<TKey, TVal>>>(),
                  DataTypeImpl::GetType<std::vector<std::map<TKey, TVal>>>()->GetDeleteFunc());
    output_data_.push_back(Data(NodeArg(name, &VectorOfMapType<TKey, TVal>::s_vec_map_type_proto), std::move(ml_value),
                                optional<float>(), optional<float>()));
  }

  void AddCustomOpRegistry(std::shared_ptr<CustomRegistry> registry) {
    custom_schema_registries_.push_back(registry->GetOpschemaRegistry());
    custom_session_registries_.push_back(registry);
  }

  void SetOutputAbsErr(const char* name, float v);
  void SetOutputRelErr(const char* name, float v);

  // Number of times to call InferenceSession::Run. The same feeds are used each time.
  // e.g. used to verify the generator ops behave as expected
  void SetNumRunCalls(int n) {
    ORT_ENFORCE(n > 0);
    num_run_calls_ = n;
  }

  template <typename T>
  void AddAttribute(std::string name, T value) {
    // Generate a the proper AddAttribute call for later
    add_attribute_funcs_.emplace_back([name = std::move(name), value = std::move(value)](onnxruntime::Node& node) {
      node.AddAttribute(name, value);
    });
  }

  enum class ExpectResult { kExpectSuccess,
                            kExpectFailure };

  void Run(ExpectResult expect_result = ExpectResult::kExpectSuccess, const std::string& expected_failure_string = "",
           const std::unordered_set<std::string>& excluded_provider_types = {},
           const RunOptions* run_options = nullptr,
           std::vector<std::unique_ptr<IExecutionProvider>>* execution_providers = nullptr,
           ExecutionMode execution_mode = ExecutionMode::ORT_SEQUENTIAL);

  void Run(SessionOptions session_options,
           ExpectResult expect_result = ExpectResult::kExpectSuccess,
           const std::string& expected_failure_string = "",
           const std::unordered_set<std::string>& excluded_provider_types = {},
           const RunOptions* run_options = nullptr,
           std::vector<std::unique_ptr<IExecutionProvider>>* execution_providers = nullptr);

  struct Data {
    onnxruntime::NodeArg def_;
    OrtValue data_;
    optional<float> relative_error_;
    optional<float> absolute_error_;
    bool sort_output_;
    Data(onnxruntime::NodeArg&& def, OrtValue&& data, optional<float>&& rel, optional<float>&& abs,
         bool sort_output = false)
        : def_(std::move(def)),
          data_(std::move(data)),
          relative_error_(std::move(rel)),
          absolute_error_(abs),
          sort_output_(sort_output) {}
    Data(Data&&) = default;
    Data& operator=(Data&&) = default;
  };

 protected:
  virtual void AddNodes(onnxruntime::Graph& graph, std::vector<onnxruntime::NodeArg*>& graph_input_defs,
                        std::vector<onnxruntime::NodeArg*>& graph_output_defs,
                        std::vector<std::function<void(onnxruntime::Node& node)>>& add_attribute_funcs);

  void AddInitializers(onnxruntime::Graph& graph);

  void FillFeedsAndOutputNames(std::unordered_map<std::string, OrtValue>& feeds,
                               std::vector<std::string>& output_names);

  std::unique_ptr<onnxruntime::Model> BuildGraph();

  const char* op_;

#ifndef NDEBUG
  bool run_called_{};
#endif

 private:
  template <typename T>
  void AddData(std::vector<Data>& data, const char* name, const std::vector<int64_t>& dims, const T* values,
               int64_t values_count, bool is_initializer = false, bool sort_output = false) {
    try {
      TensorShape shape{dims};
      ORT_ENFORCE(shape.Size() == values_count, values_count, " input values doesn't match tensor size of ",
                  shape.Size());

      auto allocator = test::AllocatorManager::Instance().GetAllocator(CPU);
      auto p_tensor = onnxruntime::make_unique<Tensor>(DataTypeImpl::GetType<T>(), shape, allocator);

      auto* data_ptr = p_tensor->template MutableData<T>();
      for (int64_t i = 0; i < values_count; i++) {
        data_ptr[i] = values[i];
      }

      std::vector<int64_t> dims_for_proto{dims};
      if (add_symbolic_dim_to_tensor_data_ >= 0 &&
          dims.size() > static_cast<size_t>(add_symbolic_dim_to_tensor_data_)) {
        dims_for_proto[add_symbolic_dim_to_tensor_data_] = -1;
      }

      TTypeProto<T> type_proto(add_shape_to_tensor_data_ ? &dims_for_proto : nullptr);
      OrtValue value;
      value.Init(p_tensor.release(), DataTypeImpl::GetType<Tensor>(),
                 DataTypeImpl::GetType<Tensor>()->GetDeleteFunc());
      data.push_back(Data(NodeArg(name, &type_proto), std::move(value), optional<float>(), optional<float>(), sort_output));
      if (is_initializer) initializer_index_.push_back(data.size() - 1);
    } catch (const std::exception& ex) {
      std::cerr << "AddData for '" << name << "' threw: " << ex.what();
      throw;
    }
  }

  template <typename T>
  void AddSeqData(std::vector<Data>& data, const char* name, const SeqTensors<T>& seq_tensors) {
    auto num_tensors = seq_tensors.tensors.size();
    std::vector<Tensor> tensors;
    tensors.resize(num_tensors);
    auto elem_type = DataTypeImpl::GetType<T>();
    for (size_t i = 0; i < num_tensors; ++i) {
      TensorShape shape{seq_tensors.tensors[i].shape};
      auto values_count = static_cast<int64_t>(seq_tensors.tensors[i].data.size());
      ORT_ENFORCE(shape.Size() == values_count, values_count,
                  " input values doesn't match tensor size of ", shape.Size());

      auto allocator = test::AllocatorManager::Instance().GetAllocator(CPU);
      auto& tensor = tensors[i];

      tensor = Tensor(elem_type,
                      shape,
                      allocator);

      auto* data_ptr = tensor.template MutableData<T>();
      for (int64_t x = 0; x < values_count; ++x) {
        data_ptr[x] = seq_tensors.tensors[i].data[x];
      }
    }

    OrtValue value;
    auto mltype = DataTypeImpl::GetType<TensorSeq>();
    auto ptr = onnxruntime::make_unique<TensorSeq>(elem_type);
    ptr->SetElements(std::move(tensors));
    value.Init(ptr.get(), mltype, mltype->GetDeleteFunc());
    ptr.release();
    data.push_back(Data(NodeArg(name, &SequenceTensorType<T>::s_sequence_tensor_type_proto), std::move(value),
                        optional<float>(), optional<float>()));
  }

  void ExecuteModel(Model& model, InferenceSession& session_object, ExpectResult expect_result,
                    const std::string& expected_failure_string, const RunOptions* run_options,
                    std::unordered_map<std::string, OrtValue> feeds, std::vector<std::string> output_names,
                    const std::string& provider_type);

  const char* domain_;
  int opset_version_;
  bool add_shape_to_tensor_data_ = true;
  int add_symbolic_dim_to_tensor_data_ = -1;
  int num_run_calls_ = 1;
  std::vector<Data> input_data_;
  std::vector<Data> output_data_;
  std::vector<size_t> initializer_index_;
  std::vector<std::function<void(onnxruntime::Node& node)>> add_attribute_funcs_;

  IOnnxRuntimeOpSchemaRegistryList custom_schema_registries_;
  std::vector<std::shared_ptr<CustomRegistry>> custom_session_registries_;
};

template <typename TException>
void ExpectThrow(OpTester& test, const std::string& error_msg) {
  try {
    test.Run();
    // should throw and not reach this
    EXPECT_TRUE(false) << "Expected Run() to throw";
  } catch (TException ex) {
    EXPECT_THAT(ex.what(), testing::HasSubstr(error_msg));
  }
}

void DebugTrap();

void Check(const OpTester::Data& expected_data, const Tensor& output_tensor, const std::string& provider_type);

// Only used for CUDA test since no toher kernel has float 16 support
#ifdef USE_CUDA
inline void ConvertFloatToMLFloat16(const float* f_datat, MLFloat16* h_data, int input_size) {
  auto in_vector = ConstEigenVectorMap<float>(f_datat, input_size);
  auto output_vector = EigenVectorMap<Eigen::half>(static_cast<Eigen::half*>(static_cast<void*>(h_data)), input_size);
  output_vector = in_vector.template cast<Eigen::half>();
}
#endif

inline void ConvertMLFloat16ToFloat(const MLFloat16* h_data, float* f_data, int input_size) {
  auto in_vector =
      ConstEigenVectorMap<Eigen::half>(static_cast<const Eigen::half*>(static_cast<const void*>(h_data)), input_size);
  auto output_vector = EigenVectorMap<float>(f_data, input_size);
  output_vector = in_vector.template cast<float>();
}

}  // namespace test
}  // namespace onnxruntime

max_stars_repo_name: MaximKalininMS/onnxruntime

max_issues_repo_name: MaximKalininMS/onnxruntime

max_forks_repo_name: MaximKalininMS/onnxruntime


text:
#ifndef SPECTRALSUBTRACTION_H
#define SPECTRALSUBTRACTION_H

#include <stdio.h>
#include <assert.h>
#include <float.h>
#include <gsl/gsl_block.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_fft_complex.h>
#include <common/refcount.h>
#include "common/jexception.h"

#include "stream/stream.h"
#include "modulated/modulated.h"

class PSDEstimator {

 public:
  PSDEstimator(unsigned fftLen2);
  ~PSDEstimator();

  bool read_estimates( const String& fn );
  bool write_estimates( const String& fn );

  const gsl_vector* estimate() const {
    return estimates_;
  }

 protected:
  gsl_vector* estimates_; /* estimated noise PSD */
};

typedef refcount_ptr<PSDEstimator> PSDEstimatorPtr;

/**
   @class estimate the noise PSD for spectral subtraction (SS)
   1. construct an object
   2. add a noise sample
   3. get noise estimates
 */
class AveragePSDEstimator : public PSDEstimator {
 public:
  /**
      @brief A constructor for SS
      @param unsigned fftLen2[in] the half of the FFT point
      @param double alpha[in] the forgetting factor for recursive averaging.
                              If this is negative, the average is used
                              as the noise PSD estimate.
   */
  AveragePSDEstimator(unsigned fftLen2, float alpha = -1.0 );
  ~AveragePSDEstimator();

  void clear_samples();
  const gsl_vector* average();
  bool add_sample( const gsl_vector_complex *sample );
  void clear();

 protected:
  float alpha_;
  bool sample_added_;
  list<gsl_vector *> sampleL_;
};

typedef Inherit<AveragePSDEstimator, PSDEstimatorPtr> AveragePSDEstimatorPtr;

class SpectralSubtractor : public VectorComplexFeatureStream {
public:
  SpectralSubtractor(unsigned fftLen, bool halfBandShift = false, float ft=1.0, float flooringV=0.001, const String& nm = "SpectralSubtractor");
  ~SpectralSubtractor();

  virtual const gsl_vector_complex* next(int frameX = -5);
  virtual void reset();
  void clear(){
    for(NoisePSDIterator_ itr = noisePSDList_.begin(); itr != noisePSDList_.end(); itr++)
      (*itr)->clear();
  }

  void set_noise_over_estimation_factor(float ft){ ft_ = ft; }
  void set_channel(VectorComplexFeatureStreamPtr& chan, double alpha=-1 );
  void start_training(){ training_started_ = true; }
  void stop_training();
  void clear_noise_samples();
  void start_noise_subtraction(){ start_noise_subtraction_ = true; }
  void stop_noise_subtraction(){ start_noise_subtraction_ = false; }
  bool read_noise_file(const String& fn, unsigned idx=0);
  bool write_noise_file(const String& fn, unsigned idx=0){ return noisePSDList_.at(idx)->write_estimates(fn); }

#ifdef ENABLE_LEGACY_BTK_API
  void setNoiseOverEstimationFactor(float ft){ set_noise_over_estimation_factor(ft); }
  void setChannel(VectorComplexFeatureStreamPtr& chan, double alpha=-1){ set_channel(chan, alpha); }
  void startTraining(){ start_training(); }
  void stopTraining(){ stop_training(); }
  void clearNoiseSamples(){ clear_noise_samples(); }
  void startNoiseSubtraction(){ start_noise_subtraction(); }
  void stopNoiseSubtraction(){ stop_noise_subtraction(); }
  bool readNoiseFile( const String& fn, unsigned idx=0 ){ return read_noise_file(fn, idx); }
  bool writeNoiseFile( const String& fn, unsigned idx=0 ){ return write_noise_file(fn, idx); }
#endif

 protected:
  typedef list<VectorComplexFeatureStreamPtr>	ChannelList_;
  typedef ChannelList_::iterator		ChannelIterator_;
  typedef vector<AveragePSDEstimatorPtr>	NoisePSDList_;
  typedef NoisePSDList_::iterator		NoisePSDIterator_;

  ChannelList_		channelList_;
  NoisePSDList_         noisePSDList_;
  unsigned		fftLen_;
  unsigned		fftLen2_;
  bool			halfBandShift_;
  bool                  training_started_;
  unsigned              totalTrainingSampleN_;
  float			ft_;
  float			flooringV_;
  bool                  start_noise_subtraction_;
};

typedef Inherit<SpectralSubtractor, VectorComplexFeatureStreamPtr> SpectralSubtractorPtr;

// ----- definition for class 'WienerFilter' -----
//
class WienerFilter : public VectorComplexFeatureStream {
 public:
  WienerFilter( VectorComplexFeatureStreamPtr &targetSignal, VectorComplexFeatureStreamPtr &noiseSignal, bool halfBandShift=false, float alpha=0.0, float flooringV=0.001, double beta=1.0, const String& nm = "WienerFilter");
  ~WienerFilter();
  virtual const gsl_vector_complex* next(int frameX = -5);
  virtual void reset();

  void    set_noise_amplification_factor(double beta){ beta_ = beta; }
  void    start_updating_noise_PSD(){ update_noise_PSD_ = true; }
  void    stop_updating_noise_PSD(){ update_noise_PSD_ = false; }

#ifdef ENABLE_LEGACY_BTK_API
  void    setNoiseAmplificationFactor(double beta){ set_noise_amplification_factor(beta); }
  void    startUpdatingNoisePSD(){ start_updating_noise_PSD(); }
  void    stopUpdatingNoisePSD(){ stop_updating_noise_PSD(); }
#endif

 private:
  gsl_vector *prev_PSDs_;
  gsl_vector *prev_PSDn_;
  VectorComplexFeatureStreamPtr target_signal_;
  VectorComplexFeatureStreamPtr noise_signal_;
  bool                          halfBandShift_;
  float			alpha_; // forgetting factor
  float			flooringV_;
  float                 beta_; // amplification coefficient for a noise signal
  bool                  update_noise_PSD_;
  unsigned		fftLen_;
  unsigned		fftLen2_;
};

typedef Inherit<WienerFilter, VectorComplexFeatureStreamPtr> WienerFilterPtr;

#endif


text:
#include <stdio.h>
#include <gsl/gsl_qrng.h>

int
main (void)
{
  int i;
  gsl_qrng * q = gsl_qrng_alloc (gsl_qrng_sobol, 2);

  for (i = 0; i < 1024; i++)
    {
      double v[2];
      gsl_qrng_get (q, v);
      printf ("%.5f %.5f\n", v[0], v[1]);
    }

  gsl_qrng_free (q);
  return 0;
}

ext: c

max_stars_repo_name: manggoguy/parsec-modified

max_issues_repo_name: Brian-ning/HMNE

max_forks_repo_name: Brian-ning/HMNE


text:
/*
 *  Copyright (C) 2021 FISCO BCOS.
 *  SPDX-License-Identifier: Apache-2.0
 *  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.
 *
 * @brief interface for TransactionReceipt
 * @file TransactionReceipt.h
 */
#pragma once

#include "ProtocolTypeDef.h"
#include <bcos-crypto/interfaces/crypto/CryptoSuite.h>
#include <bcos-utilities/FixedBytes.h>
#include <gsl/span>

namespace bcos
{
namespace protocol
{
class LogEntry;
class TransactionReceipt
{
public:
    using Ptr = std::shared_ptr<TransactionReceipt>;
    using ConstPtr = std::shared_ptr<const TransactionReceipt>;
    explicit TransactionReceipt(bcos::crypto::CryptoSuite::Ptr _cryptoSuite)
      : m_cryptoSuite(_cryptoSuite)
    {}

    virtual ~TransactionReceipt() {}

    virtual void decode(bytesConstRef _receiptData) = 0;
    virtual void encode(bytes& _encodedData) const = 0;
    virtual bytesConstRef encode(bool _onlyHashFieldData = false) const = 0;

    virtual bcos::crypto::HashType hash() const
    {
        auto hashFields = encode(true);
        return m_cryptoSuite->hash(hashFields);
    }

    virtual int32_t version() const = 0;
    virtual u256 gasUsed() const = 0;  // TODO: remove from hash
    virtual std::string_view contractAddress() const = 0;
    virtual int32_t status() const = 0;
    virtual bytesConstRef output() const = 0;
    virtual gsl::span<const LogEntry> logEntries() const = 0;
    virtual bcos::crypto::CryptoSuite::Ptr cryptoSuite() { return m_cryptoSuite; }
    virtual BlockNumber blockNumber() const = 0;

    // additional information on transaction execution, no need to be involved in the hash
    // calculation
    virtual std::string const& message() const = 0;
    virtual void setMessage(std::string const& _message) = 0;
    virtual void setMessage(std::string&& _message) = 0;

protected:
    bcos::crypto::CryptoSuite::Ptr m_cryptoSuite;
};
using Receipts = std::vector<TransactionReceipt::Ptr>;
using ReceiptsPtr = std::shared_ptr<Receipts>;
using ReceiptsConstPtr = std::shared_ptr<const Receipts>;
}  // namespace protocol
}  // namespace bcos

max_stars_repo_name: contropist/FISCO-BCOS

max_issues_repo_name: contropist/FISCO-BCOS

max_forks_repo_name: contropist/FISCO-BCOS


text:
#ifndef PFLOW_H
#define PFLOW_H

#include <petsc.h>

#define epsilon 1E-8 /**< epsilon value for finite differences */
#define MAXLINE 1000 /**< Max. number of characters in a line */
#define ISOLATED_BUS 4 /**< Isolated bus */
#define REF_BUS 3 /**< Reference bus (swing bus) */
#define PV_BUS 2 /**< PV (voltage-controlled) bus */
#define PQ_BUS 1 /**< PQ bus */
#define NGEN_AT_BUS_MAX 15 /**< Maximum number of generators allowed at a bus */
#define NLOAD_AT_BUS_MAX 10 /**< Maximum number of loads allowed at a bus */
#define NPHASE 1 /**< Per-phase analysis */

typedef void* PFLOW;

extern PetscErrorCode PFLOWCreate(MPI_Comm,PFLOW*);
extern PetscErrorCode PFLOWDestroy(PFLOW*);
extern PetscErrorCode PFLOWReadMatPowerData(PFLOW,const char[]);
extern PetscErrorCode PFLOWSolve(PFLOW);
extern PetscErrorCode PFLOWGetBusVoltage(PFLOW,PetscInt,PetscScalar*,PetscScalar*,PetscBool*);
extern PetscErrorCode PFLOWSetLoadPower(PFLOW,PetscInt,PetscScalar,PetscScalar);

#endif

max_stars_repo_name: GMLC-TDC/Use-Cases

max_issues_repo_name: GMLC-TDC/Use-Cases

max_forks_repo_name: GMLC-TDC/Use-Cases


text:
/* specfunc/clausen.c
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/* Author:  G. Jungman */

#include <config.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_sf_trig.h>
#include <gsl/gsl_sf_clausen.h>

#include "chebyshev.h"
#include "cheb_eval.c"

static double aclaus_data[15] = {
  2.142694363766688447e+00,
  0.723324281221257925e-01,
  0.101642475021151164e-02,
  0.3245250328531645e-04,
  0.133315187571472e-05,
  0.6213240591653e-07,
  0.313004135337e-08,
  0.16635723056e-09,
  0.919659293e-11,
  0.52400462e-12,
  0.3058040e-13,
  0.18197e-14,
  0.1100e-15,
  0.68e-17,
  0.4e-18
};
static cheb_series aclaus_cs = {
  aclaus_data,
  14,
  -1, 1,
  8  /* FIXME:  this is a guess, correct value needed here BJG */
};

/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/

int gsl_sf_clausen_e(double x, gsl_sf_result *result)
{
  const double x_cut = M_PI * GSL_SQRT_DBL_EPSILON;

  double sgn = 1.0;
  int status_red;

  if(x < 0.0) {
    x   = -x;
    sgn = -1.0;
  }

  /* Argument reduction to [0, 2pi) */
  status_red = gsl_sf_angle_restrict_pos_e(&x);

  /* Further reduction to [0,pi) */
  if(x > M_PI) {
    /* simulated extra precision: 2PI = p0 + p1 */
    const double p0 = 6.28125;
    const double p1 = 0.19353071795864769253e-02;
    x = (p0 - x) + p1;
    sgn = -sgn;
  }

  if(x == 0.0) {
    result->val = 0.0;
    result->err = 0.0;
  }
  else if(x < x_cut) {
    result->val = x * (1.0 - log(x));
    result->err = x * GSL_DBL_EPSILON;
  }
  else {
    const double t = 2.0*(x*x / (M_PI*M_PI) - 0.5);
    gsl_sf_result result_c;
    cheb_eval_e(&aclaus_cs, t, &result_c);
    result->val = x * (result_c.val - log(x));
    result->err = x * (result_c.err + GSL_DBL_EPSILON);
  }

  result->val *= sgn;

  return status_red;
}

/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/

#include "eval.h"

double gsl_sf_clausen(const double x)
{
  EVAL_RESULT(gsl_sf_clausen_e(x, &result));
}

max_stars_repo_name: ielomariala/Hex-Game


text:
/**
 *
 * @file core_zlacpy_pivot.c
 *
 *  PLASMA core_blas kernel
 *  PLASMA is a software package provided by Univ. of Tennessee,
 *  Univ. of California Berkeley and Univ. of Colorado Denver
 *
 * @version 2.6.0
 * @author Mathieu Faverge
 * @date 2013-02-01
 * @precisions normal z -> c d s
 *
 **/
#include <lapacke.h>
#include "common.h"

#define A(m, n) BLKADDR(descA, PLASMA_Complex64_t, m, n)

/***************************************************************************//**
 *
 * @ingroup CORE_PLASMA_Complex64_t
 *
 *  CORE_zlacpy_pivot extracts the original version of the rows selected by the
 *  ipiv array and copies them into a new buffer.
 *
 *  This kernel is used by tournament pivoting algorithms, to extract the
 *  selected rows from the original matrix that will make it to the next level
 *  of the tournament.
 *
 *******************************************************************************
 *
 *  @param[in] descA
 *          The descriptor of the matrix A in which the kernel will extract the
 *          original rows.
 *
 *  @param[in] direct
 *          @arg PlasmaRowwise: The extracted rows are stored in column major layout.
 *          @arg PlasmaColumnwise: The extracted rows are store in row major layout.
 *
 *  @param[in] k1
 *          The first element of IPIV for which a row interchange will
 *          be done.
 *
 *  @param[in] k2
 *          The last element of IPIV for which a row interchange will
 *          be done.
 *
 *  @param[in] ipiv
 *          The pivot indices; Only the element in position k1 to k2
 *          are accessed. The pivots should be included in the interval 1 to A.m
 *
 *  @param[in,out] rankin
 *          On entry, the global indices relative to the full matrix A
 *          factorized, in the local sub-matrix. If init == 1, rankin is
 *          initialized to A.i, .. A.i+descA.m
 *          On exit, rows are permutted according to ipiv.
 *
 *  @param[out] rankout
 *          On exit, contains the global indices of the first (k2-k1+1) rows.
 *
 *  @param[out] A
 *          An lda-by-descA.n matrix. On exit, A contains the original version
 *          of the rows selected by the pivoting process.
 *
 *  @param[in] lda
 *          The leading dimension of the array A.  lda >= max(1,(k2-k1+1)).
 *
 *  @param[in] init
 *          True if rankin needs to be initialized.
 *          False, if rankin contains already initialized data.
 *
 *******************************************************************************
 *
 * @return
 *         \retval PLASMA_SUCCESS successful exit
 *         \retval <0 if INFO = -k, the k-th argument had an illegal value
 *
 ******************************************************************************/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_zlacpy_pivot = PCORE_zlacpy_pivot
#define CORE_zlacpy_pivot PCORE_zlacpy_pivot
#endif
int CORE_zlacpy_pivot( const PLASMA_desc descA,
                       PLASMA_enum direct, int k1, int k2, const int *ipiv,
                       int *rankin, int *rankout,
                       PLASMA_Complex64_t *A, int lda,
                       int init)
{
    int i, ip, it, ir, ld;
    const int *lpiv;
    int *ro = rankout;

    /* Init rankin if first step */
    if ( init ) {
        int val = descA.i;
        for(i=0; i<descA.m; i++, val++) {
            rankin[i] = val;
        }
    }

    /* Generate the rankout */
    ro = rankout;
    lpiv = ipiv;
    for(i=k1-1; i<k2; i++, ro++, lpiv++) {
        *ro = rankin[ (*lpiv) - 1 ];
        rankin[ (*lpiv) - 1 ] = rankin[ i ];
    }

    /* Extract the rows */
    if (direct == PlasmaRowwise) {
       ro = rankout;
       for(i=k1-1; i<k2; i++, ro++) {
           ip = (*ro) - descA.i;
           it = ip / descA.mb;
           ir = ip % descA.mb;
           ld = BLKLDD(descA, it);
           cblas_zcopy(descA.n, A(it, 0) + ir, ld,
                                A + i,         lda );
       }
    }
    else {
       ro = rankout;
       for(i=k1-1; i<k2; i++, ro++) {
           ip = (*ro) - descA.i;
           it = ip / descA.mb;
           ir = ip % descA.mb;
           ld = BLKLDD(descA, it);
           cblas_zcopy(descA.n, A(it, 0) + ir, ld,
                                A + i*lda,     1 );
       }
    }
    return PLASMA_SUCCESS;
}


text:
#pragma once

#include <imageview/IsPixelFormat.h>
#include <imageview/internal/ImageViewIterator.h>
#include <imageview/internal/ImageViewStorage.h>
#include <imageview/internal/PixelRef.h>

#include <gsl/assert>
#include <gsl/span>

#include <cstddef>
#include <stdexcept>

namespace imageview {

template <class PixelFormat, bool Mutable = false>
class ImageRowView {
 public:
  static_assert(IsPixelFormat<PixelFormat>::value, "Not a PixelFormat.");

  using byte_type = std::conditional_t<Mutable, std::byte, const std::byte>;
  using value_type = typename PixelFormat::color_type;
  // TODO: consider using 'const value_type' instead of 'value_type' for immutable views.
  using reference = std::conditional_t<Mutable, detail::PixelRef<PixelFormat>, value_type>;

  // Constant LegacyInputIterator whose value_type is @value_type. The type satisfies all
  // requirements of LegacyRandomAccessIterator except the multipass guarantee: for dereferenceable iterators a and b
  // with a == b, there is no requirement that *a and *b are bound to the same object.
  using const_iterator = detail::ImageViewIterator<PixelFormat, false>;
  using iterator = detail::ImageViewIterator<PixelFormat, Mutable>;

  // Constructs an empty view.
  // This constructor is only available if PixelFormat is default-constructible.
  template <class Enable = std::enable_if_t<std::is_default_constructible_v<PixelFormat>>>
  constexpr ImageRowView() noexcept(noexcept(std::is_nothrow_default_constructible_v<PixelFormat>)){};

  // Constructs an empty view.
  // \param pixel_format - instance of PixelFormat to use.
  constexpr explicit ImageRowView(const PixelFormat& pixel_format) noexcept(
      noexcept(std::is_nothrow_copy_constructible_v<PixelFormat>));

  // Constructs an empty view.
  // \param pixel_format - instance of PixelFormat to use.
  constexpr explicit ImageRowView(PixelFormat&& pixel_format) noexcept(
      noexcept(std::is_nothrow_move_constructible_v<PixelFormat>));

  // Constructs a flat view into the given bitmap.
  // This constructor is only available if PixelFormat is default-constructible.
  // \param data - bitmap data.
  // \param width - the number of pixels in the bitmap.
  //
  // Expects(data.size() == width * PixelFormat::kBytesPerPixel)
  template <class Enable = std::enable_if_t<std::is_default_constructible_v<PixelFormat>>>
  constexpr ImageRowView(gsl::span<byte_type> data,
                         std::size_t width) noexcept(noexcept(std::is_nothrow_default_constructible_v<PixelFormat>));

  // Constructs a flat view into the given bitmap.
  // \param data - bitmap data.
  // \param width - the number of pixels in the bitmap.
  // \param pixel_format - instance of PixelFormat to use.
  //
  // Expects(data.size() == width * PixelFormat::kBytesPerPixel)
  constexpr ImageRowView(gsl::span<byte_type> data, std::size_t width, const PixelFormat& pixel_format) noexcept(
      noexcept(std::is_nothrow_copy_constructible_v<PixelFormat>));

  // Constructs a flat view into the given bitmap.
  // \param data - bitmap data.
  // \param width - the number of pixels in the bitmap.
  // \param pixel_format - instance of PixelFormat to use.
  //
  // Expects(data.size() == width * PixelFormat::kBytesPerPixel)
  constexpr ImageRowView(gsl::span<byte_type> data, std::size_t width, PixelFormat&& pixel_format) noexcept(
      noexcept(std::is_nothrow_move_constructible_v<PixelFormat>));

  // Construct a read-only view from a mutable view.
  template <class Enable = std::enable_if_t<!Mutable>>
  constexpr ImageRowView(ImageRowView<PixelFormat, !Mutable> row_view);

  // Returns the pixel format used by this image.
  constexpr const PixelFormat& pixelFormat() const noexcept;

  // Returns the bitmap data.
  constexpr gsl::span<byte_type> data() const noexcept;

  // Returns the total number of pixels in this view.
  constexpr std::size_t size() const noexcept;

  // Returns true if the view is empty (i.e. has 0 pixels), false otherwise.
  constexpr bool empty() const noexcept;

  // Returns the size of the referenced bitmap in bytes, i.e.
  //   size() * PixelFormat::kBytesPerPixel
  constexpr std::size_t size_bytes() const noexcept;

  // Returns an iterator to the first pixel.
  constexpr iterator begin() const;

  // Returns a const iterator to the first pixel.
  constexpr const_iterator cbegin() const;

  // Returns an iterator past the last pixel.
  constexpr iterator end() const;

  // Returns a const iterator past the last pixel.
  constexpr const_iterator cend() const;

  // Returns the color of the specified pixel.
  // \param index - 0-based index of the pixel. No bounds checking is performed - the behavior is undefined if @index is
  // outside [0; size()).
  constexpr reference operator[](std::size_t index) const;

  // Returns the color of the specified pixel.
  // \param index - 0-based index of the pixel.
  // \throw std::out_of_range if @index is outside [0; size()).
  constexpr reference at(std::size_t index) const;

 private:
  detail::ImageViewStorage<PixelFormat, Mutable> storage_;
  std::size_t width_ = 0;
};

template <class PixelFormat, bool Mutable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(const PixelFormat& pixel_format) noexcept(
    noexcept(std::is_nothrow_copy_constructible_v<PixelFormat>))
    : storage_(nullptr, pixel_format) {}

template <class PixelFormat, bool Mutable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(PixelFormat&& pixel_format) noexcept(
    noexcept(std::is_nothrow_move_constructible_v<PixelFormat>))
    : storage_(nullptr, std::move(pixel_format)) {}

template <class PixelFormat, bool Mutable>
template <class Enable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(gsl::span<byte_type> data, std::size_t width) noexcept(
    noexcept(std::is_nothrow_default_constructible_v<PixelFormat>))
    : storage_(data.data()), width_(width) {
  Expects(data.size() == width * PixelFormat::kBytesPerPixel);
}

template <class PixelFormat, bool Mutable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(
    gsl::span<byte_type> data, std::size_t width,
    const PixelFormat& pixel_format) noexcept(noexcept(std::is_nothrow_copy_constructible_v<PixelFormat>))
    : storage_(data.data(), pixel_format), width_(width) {
  Expects(data.size() == width * PixelFormat::kBytesPerPixel);
}

template <class PixelFormat, bool Mutable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(
    gsl::span<byte_type> data, std::size_t width,
    PixelFormat&& pixel_format) noexcept(noexcept(std::is_nothrow_move_constructible_v<PixelFormat>))
    : storage_(data.data(), std::move(pixel_format)), width_(width) {
  Expects(data.size() == width * PixelFormat::kBytesPerPixel);
}

template <class PixelFormat, bool Mutable>
template <class Enable>
constexpr ImageRowView<PixelFormat, Mutable>::ImageRowView(ImageRowView<PixelFormat, !Mutable> row_view)
    : ImageRowView(row_view.data(), row_view.size(), row_view.pixelFormat()) {}

template <class PixelFormat, bool Mutable>
constexpr const PixelFormat& ImageRowView<PixelFormat, Mutable>::pixelFormat() const noexcept {
  return storage_.pixelFormat();
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::data() const noexcept -> gsl::span<byte_type> {
  return gsl::span<byte_type>(storage_.data(), size_bytes());
}

template <class PixelFormat, bool Mutable>
constexpr std::size_t ImageRowView<PixelFormat, Mutable>::size() const noexcept {
  return width_;
}

template <class PixelFormat, bool Mutable>
constexpr bool ImageRowView<PixelFormat, Mutable>::empty() const noexcept {
  return width_ == 0;
}

template <class PixelFormat, bool Mutable>
constexpr std::size_t ImageRowView<PixelFormat, Mutable>::size_bytes() const noexcept {
  return width_ * PixelFormat::kBytesPerPixel;
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::begin() const -> iterator {
  return iterator(storage_.data_, storage_.pixelFormat());
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::cbegin() const -> const_iterator {
  return const_iterator(storage_.data_, storage_.pixelFormat());
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::end() const -> iterator {
  return iterator(storage_.data_ + width_ * PixelFormat::kBytesPerPixel, storage_.pixelFormat());
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::cend() const -> const_iterator {
  return const_iterator(storage_.data_ + width_ * PixelFormat::kBytesPerPixel, storage_.pixelFormat());
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::operator[](std::size_t index) const -> reference {
  const gsl::span<byte_type, PixelFormat::kBytesPerPixel> pixel_data(
      storage_.data() + index * PixelFormat::kBytesPerPixel, PixelFormat::kBytesPerPixel);
  if constexpr (Mutable) {
    return detail::PixelRef<PixelFormat>(pixel_data, pixelFormat());
  } else {
    return pixelFormat().read(pixel_data);
  }
}

template <class PixelFormat, bool Mutable>
constexpr auto ImageRowView<PixelFormat, Mutable>::at(std::size_t index) const -> reference {
  if (index >= width_) {
    throw std::out_of_range("ImageRowView::at(): attempting to access an element out of range.");
  }
  return (*this)[index];
}

}  // namespace imageview

max_stars_repo_name: alexanderbelous/imageview

max_issues_repo_name: alexanderbelous/imageview

max_forks_repo_name: alexanderbelous/imageview


text:
#ifndef VKST_WSI_WINDOW_H
#define VKST_WSI_WINDOW_H

#include <turf/c/core.h>
#include <gsl.h>
#include <wsi/input.h>
#include <functional>

namespace wsi {

enum class window_options : uint8_t {
  none = 0,
  decorated = (1 << 1),
  sizeable = (1 << 2),
  fullscreen_windowed = (1 << 3),
}; // enum class window_options

namespace impl {

template <class D>
class window {
public:
  void retitle(gsl::czstring title) noexcept {
    static_cast<D*>(this)->do_retitle(title);
  }
  std::string title() const noexcept {
    return static_cast<D const*>(this)->do_title();
  }

  rect2d const& topleft_size() const noexcept { return _topleft_size; }

  extent2d const& size() const noexcept { return _topleft_size.extent; }
  void resize(extent2d const& size) noexcept {
    static_cast<D*>(this)->do_resize(size);
  }

  offset2d const& position() const noexcept { return _topleft_size.offset; }
  void reposition(offset2d const& position) noexcept {
    static_cast<D*>(this)->do_reposition(position);
  }

  void show() noexcept { static_cast<D*>(this)->do_show(); }
  void hide() noexcept { static_cast<D*>(this)->do_hide(); }

  void close() noexcept { static_cast<D*>(this)->do_close(); }
  bool closed() const noexcept { return _closed; }

  keyset const& keys() const noexcept { return _keys; }
  buttonset const& buttons() const noexcept { return _buttons; }
  int scroll() const noexcept { return _scroll; }

  offset2d cursor_pos() const noexcept {
    return static_cast<D const*>(this)->do_cursor_pos();
  }

  void poll_events() noexcept { static_cast<D*>(this)->do_poll_events(); }

  using resize_delegate = std::function<void(D*, extent2d const&)>;
  void on_resize(resize_delegate delegate) noexcept {
    _on_resize = std::move(delegate);
  }

  using reposition_delegate = std::function<void(D*, offset2d const&)>;
  void on_reposition(reposition_delegate delegate) noexcept {
    _on_reposition = std::move(delegate);
  }

  using close_delegate = std::function<void(D*)>;
  void on_close(close_delegate delegate) noexcept {
    _on_close = std::move(delegate);
  }

  constexpr window() noexcept {}
  constexpr window(rect2d topleft_size) noexcept
  : _topleft_size{std::move(topleft_size)} {}

protected:
  rect2d _topleft_size{};
  bool _closed{false};
  keyset _keys{};
  buttonset _buttons{};
  int _scroll{0};

  resize_delegate _on_resize{[](auto, auto) {}};
  reposition_delegate _on_reposition{[](auto, auto) {}};
  close_delegate _on_close{[](D*) {}};
}; // class window

} // namespace impl

inline constexpr auto operator|(window_options a, window_options b) noexcept {
  using U = std::underlying_type_t<window_options>;
  return static_cast<window_options>(static_cast<U>(a) | static_cast<U>(b));
}

inline constexpr auto operator&(window_options a, window_options b) noexcept {
  using U = std::underlying_type_t<window_options>;
  return static_cast<window_options>(static_cast<U>(a) & static_cast<U>(b));
}

} // namespace wsi

// clang-format off
#if TURF_TARGET_WIN32
#  include <wsi/window_win32.h>
#elif TURF_KERNEL_LINUX
#  include <wsi/window_xlib.h>
#else
#  error "Unsupported platform"
#endif
// clang-format on

#endif // VKST_WSI_WINDOW_H

max_stars_repo_name: wesleygriffin/vkst

max_issues_repo_name: wesleygriffin/vkst

max_forks_repo_name: wesleygriffin/vkst


text:
#ifndef __SVM_MAIN_H__
#define __SVM_MAIN_H__

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stdlib.h>
#include <gsl_vector.h>
#include <gsl_multimin.h>
#include "common.h"
#include "smo.h"
#include "kernels.h"

// returns vector normal to hyperplane and margin width
PyObject* __get_w_b(PyObject* elements, int k_type, double C);
input_data_t* process_input_data(PyObject* n_array, int k_type, double C);

#endif  /* __SVM_MAIN_H__ */