text:
/*
 * Copyright 2010-2012 Esrille 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.
 */

#include "DocumentImp.h"

#include <algorithm>
#include <new>
#include <vector>
#include <boost/algorithm/string.hpp>

#include <org/w3c/dom/events/MouseEvent.h>

#include "CommentImp.h"
#include "DOMImplementationImp.h"
#include "DocumentTypeImp.h"
#include "ElementImp.h"
#include "EventImp.h"
#include "NodeListImp.h"
#include "ObjectArrayImp.h"
#include "TextImp.h"
#include "WindowImp.h"
#include "css/CSSSerialize.h"
#include "html/HTMLAnchorElementImp.h"
#include "html/HTMLAreaElementImp.h"
#include "html/HTMLAudioElementImp.h"
#include "html/HTMLBaseElementImp.h"
#include "html/HTMLBindingElementImp.h"
#include "html/HTMLBodyElementImp.h"
#include "html/HTMLBRElementImp.h"
#include "html/HTMLButtonElementImp.h"
#include "html/HTMLCanvasElementImp.h"
#include "html/HTMLCollectionImp.h"
#include "html/HTMLCommandElementImp.h"
#include "html/HTMLDataListElementImp.h"
#include "html/HTMLDetailsElementImp.h"
#include "html/HTMLDivElementImp.h"
#include "html/HTMLDListElementImp.h"
#include "html/HTMLEmbedElementImp.h"
#include "html/HTMLFieldSetElementImp.h"
#include "html/HTMLFormElementImp.h"
#include "html/HTMLFontElementImp.h"
#include "html/HTMLHeadElementImp.h"
#include "html/HTMLHeadingElementImp.h"
#include "html/HTMLHRElementImp.h"
#include "html/HTMLHtmlElementImp.h"
#include "html/HTMLIFrameElementImp.h"
#include "html/HTMLImageElementImp.h"
#include "html/HTMLInputElementImp.h"
#include "html/HTMLKeygenElementImp.h"
#include "html/HTMLLabelElementImp.h"
#include "html/HTMLLegendElementImp.h"
#include "html/HTMLLIElementImp.h"
#include "html/HTMLLinkElementImp.h"
#include "html/HTMLMapElementImp.h"
#include "html/HTMLMenuElementImp.h"
#include "html/HTMLMetaElementImp.h"
#include "html/HTMLMeterElementImp.h"
#include "html/HTMLModElementImp.h"
#include "html/HTMLObjectElementImp.h"
#include "html/HTMLOListElementImp.h"
#include "html/HTMLOptGroupElementImp.h"
#include "html/HTMLOptionElementImp.h"
#include "html/HTMLOutputElementImp.h"
#include "html/HTMLParagraphElementImp.h"
#include "html/HTMLParamElementImp.h"
#include "html/HTMLPreElementImp.h"
#include "html/HTMLProgressElementImp.h"
#include "html/HTMLQuoteElementImp.h"
#include "html/HTMLScriptElementImp.h"
#include "html/HTMLSelectElementImp.h"
#include "html/HTMLSpanElementImp.h"
#include "html/HTMLSourceElementImp.h"
#include "html/HTMLStyleElementImp.h"
#include "html/HTMLTableCaptionElementImp.h"
#include "html/HTMLTableColElementImp.h"
#include "html/HTMLTableDataCellElementImp.h"
#include "html/HTMLTableElementImp.h"
#include "html/HTMLTableHeaderCellElementImp.h"
#include "html/HTMLTableRowElementImp.h"
#include "html/HTMLTableSectionElementImp.h"
#include "html/HTMLTemplateElementImp.h"
#include "html/HTMLTextAreaElementImp.h"
#include "html/HTMLTimeElementImp.h"
#include "html/HTMLTitleElementImp.h"
#include "html/HTMLUListElementImp.h"
#include "html/HTMLUnknownElementImp.h"
#include "html/HTMLVideoElementImp.h"

#include "Test.util.h"

namespace org { namespace w3c { namespace dom { namespace bootstrap {

DocumentImp::DocumentImp(const std::u16string& url) :
    url(url),
    ObjectMixin(static_cast<DocumentImp*>(0) /*nullptr */),
    doctype(0),
    mode(NoQuirksMode),
    readyState(u"loading"),
    compatMode(u"CSS1Compat"),
    loadEventDelayCount(1),
    contentLoaded(false),
    pendingParsingBlockingScript(0),
    defaultView(0),
    activeElement(0),
    error(0)
{
    nodeName = u"#document";
}

DocumentImp::~DocumentImp()
{
}

bool DocumentImp::processScripts(std::list<html::HTMLScriptElement>& scripts)
{
    while (!scripts.empty()) {
        auto script = dynamic_cast<HTMLScriptElementImp*>(scripts.front().self());
        if (!script->isReadyToBeParserExecuted())
            return false;
        script->execute();
        scripts.pop_front();
        decrementLoadEventDelayCount();
    }
    return true;
}

void DocumentImp::setDefaultView(WindowImp* view)
{
    defaultView = view;
}

void DocumentImp::setReadyState(const std::u16string& readyState)
{
    if (this->readyState == readyState)
        return;
    this->readyState = readyState;
    if (readyState == u"complete") {
        if (defaultView) {
            events::Event event = new(std::nothrow) EventImp;
            event.initEvent(u"load", false, false);
            defaultView->dispatchEvent(event);
            if (ElementImp* frame = defaultView->getFrameElementImp()) {
                if (getError() == 0)
                    frame->dispatchEvent(event);
                else {
                    event.initEvent(u"error", false, false);
                    frame->dispatchEvent(event);
                }
            }
        }
    }
}

void DocumentImp::resetStyleSheets()
{
    clearStyleSheets();
    html::HTMLHeadElement head = getHead();
    if (!head)
        return;
    for (auto element = head.getFirstElementChild(); element; element = element.getNextElementSibling()) {
        if (html::HTMLStyleElement::hasInstance(element)) {
            html::HTMLStyleElement styleElement = interface_cast<html::HTMLStyleElement>(element);
            stylesheets::StyleSheet styleSheet = styleElement.getSheet();
            addStyleSheet(styleSheet);
        } else if (html::HTMLLinkElement::hasInstance(element)) {
            html::HTMLLinkElement linkElement = interface_cast<html::HTMLLinkElement>(element);
            stylesheets::StyleSheet styleSheet = linkElement.getSheet();
            addStyleSheet(styleSheet);
        }
    }
}

void DocumentImp::setURL(const std::u16string& url)
{
    this->url = url;
}

void DocumentImp::setFocus(ElementImp* element)
{
    if (activeElement == element)
        return;
    if (activeElement) {
        events::Event event = new(std::nothrow) EventImp;
        event.initEvent(u"blur", false, false);
        activeElement->dispatchEvent(event);
    }
    activeElement = element;
    if (activeElement) {
        events::Event event = new(std::nothrow) EventImp;
        event.initEvent(u"focus", false, false);
        activeElement->dispatchEvent(event);
    }
}

DocumentWindowPtr DocumentImp::activate()
{
    if (defaultView)
        return defaultView->activate();
    return 0;
}

unsigned DocumentImp::decrementLoadEventDelayCount() {
    assert(0 < loadEventDelayCount);
    if (--loadEventDelayCount == 0) {
        setReadyState(u"complete");
    }
    return loadEventDelayCount;
}

// Document

DOMImplementation DocumentImp::getImplementation()
{
    return getDOMImplementation();
}

std::u16string DocumentImp::getDocumentURI()
{
    return url;
}

void DocumentImp::setDocumentURI(const std::u16string& documentURI)
{
    if (defaultView)
        defaultView->setLocation(documentURI);
}

std::u16string DocumentImp::getCompatMode()
{
    return compatMode;
}

std::u16string DocumentImp::getContentType()
{
    // TODO: implement me!
    return u"";
}

DocumentType DocumentImp::getDoctype()
{
    return doctype;
}

Element DocumentImp::getDocumentElement()
{
    for (auto i = getFirstChild(); i; i = i.getNextSibling())
        if (i.getNodeType() == Node::ELEMENT_NODE)
            return interface_cast<Element>(i);
    return 0;
}

NodeList DocumentImp::getElementsByTagName(const std::u16string& qualifiedName)
{
    return ElementImp::getElementsByTagName(dynamic_cast<ElementImp*>(getDocumentElement().self()), qualifiedName);
}

NodeList DocumentImp::getElementsByTagNameNS(const std::u16string& _namespace, const std::u16string& localName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList DocumentImp::getElementsByClassName(const std::u16string& classNames)
{
    return ElementImp::getElementsByClassName(dynamic_cast<ElementImp*>(getDocumentElement().self()), classNames);
}

Element DocumentImp::getElementById(const std::u16string& elementId)
{
    ElementImp* e = dynamic_cast<ElementImp*>(getDocumentElement().self());
    while (e) {
        Nullable<std::u16string> id = e->getAttribute(u"id");
        if (id.hasValue() && id.value() == elementId)
            return e;
        e = e->getNextElement();
    }
    return 0;
}

Element DocumentImp::createElement(const std::u16string& localName)
{
    std::u16string name(localName);
    toLower(name);  // TODO: if html

    // Checked in the order of descriptions in the HTML specification
    if (name == u"html")
        return new(std::nothrow) HTMLHtmlElementImp(this);
    if (name == u"head")
        return new(std::nothrow) HTMLHeadElementImp(this);
    if (name == u"title")
        return new(std::nothrow) HTMLTitleElementImp(this);
    if (name == u"base")
        return new(std::nothrow) HTMLBaseElementImp(this);
    if (name == u"link")
        return new(std::nothrow) HTMLLinkElementImp(this);
    if (name == u"meta")
        return new(std::nothrow) HTMLMetaElementImp(this);
    if (name == u"style")
        return new(std::nothrow) HTMLStyleElementImp(this);
    if (name == u"script")
        return new(std::nothrow) HTMLScriptElementImp(this);
    if (name == u"noscript")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"body")
        return new(std::nothrow) HTMLBodyElementImp(this);
    if (name == u"section" ||
        name == u"nav" ||
        name == u"article" ||
        name == u"aside")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"h1" ||
        name == u"h2" ||
        name == u"h3" ||
        name == u"h4" ||
        name == u"h5" ||
        name == u"h6")
        return new(std::nothrow) HTMLHeadingElementImp(this, name);
    if (name == u"hgroup" ||
        name == u"header" ||
        name == u"footer" ||
        name == u"address")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"p")
        return new(std::nothrow) HTMLParagraphElementImp(this);
    if (name == u"hr")
        return new(std::nothrow) HTMLHRElementImp(this);
    if (name == u"pre")
        return new(std::nothrow) HTMLPreElementImp(this);
    if (name == u"blockquote")
        return new(std::nothrow) HTMLQuoteElementImp(this, name);
    if (name == u"ol")
        return new(std::nothrow) HTMLOListElementImp(this);
    if (name == u"ul")
        return new(std::nothrow) HTMLUListElementImp(this);
    if (name == u"li")
        return new(std::nothrow) HTMLLIElementImp(this);
    if (name == u"dl")
        return new(std::nothrow) HTMLDListElementImp(this);
    if (name == u"dt" ||
        name == u"dd" ||
        name == u"figure" ||
        name == u"figcaption")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"div")
        return new(std::nothrow) HTMLDivElementImp(this);
    if (name == u"a")
        return new(std::nothrow) HTMLAnchorElementImp(this);
    if (name == u"em" ||
        name == u"strong" ||
        name == u"small" ||
        name == u"s" ||
        name == u"cite")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"q")
        return new(std::nothrow) HTMLQuoteElementImp(this, name);
    if (name == u"dfn" ||
        name == u"abbr")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"time")
        return new(std::nothrow) HTMLTimeElementImp(this);
    if (name == u"code" ||
        name == u"var" ||
        name == u"samp" ||
        name == u"kbd" ||
        name == u"sub" ||
        name == u"sup" ||
        name == u"i" ||
        name == u"b" ||
        name == u"u" ||
        name == u"mark" ||
        name == u"ruby" ||
        name == u"rt" ||
        name == u"rp" ||
        name == u"bdi" ||
        name == u"bdo")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"span")
        return new(std::nothrow) HTMLSpanElementImp(this);
    if (name == u"br")
        return new(std::nothrow) HTMLBRElementImp(this);
    if (name == u"wbr")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"ins" ||
        name == u"del")
        return new(std::nothrow) HTMLModElementImp(this, name);
    if (name == u"img")
        return new(std::nothrow) HTMLImageElementImp(this);
    if (name == u"iframe")
        return new(std::nothrow) HTMLIFrameElementImp(this);
    if (name == u"embed")
        return new(std::nothrow) HTMLEmbedElementImp(this);
    if (name == u"object")
        return new(std::nothrow) HTMLObjectElementImp(this);
    if (name == u"param")
        return new(std::nothrow) HTMLParamElementImp(this);
    if (name == u"video")
        return new(std::nothrow) HTMLVideoElementImp(this);
    if (name == u"audio")
        return new(std::nothrow) HTMLAudioElementImp(this);
    if (name == u"source")
        return new(std::nothrow) HTMLSourceElementImp(this);
    if (name == u"canvas")
        return new(std::nothrow) HTMLCanvasElementImp(this);
    if (name == u"map")
        return new(std::nothrow) HTMLMapElementImp(this);
    if (name == u"area")
        return new(std::nothrow) HTMLAreaElementImp(this);
    if (name == u"table")
        return new(std::nothrow) HTMLTableElementImp(this);
    if (name == u"caption")
        return new(std::nothrow) HTMLTableCaptionElementImp(this);
    if (name == u"colgroup" ||
        name == u"col")
        return new(std::nothrow) HTMLTableColElementImp(this, name);
    if (name == u"tbody" ||
        name == u"thead" ||
        name == u"tfoot")
        return new(std::nothrow) HTMLTableSectionElementImp(this, name);
    if (name == u"tr")
        return new(std::nothrow) HTMLTableRowElementImp(this);
    if (name == u"td")
        return new(std::nothrow) HTMLTableDataCellElementImp(this);
    if (name == u"th")
        return new(std::nothrow) HTMLTableHeaderCellElementImp(this);
    if (name == u"form")
        return new(std::nothrow) HTMLFormElementImp(this);
    if (name == u"fieldset")
        return new(std::nothrow) HTMLFieldSetElementImp(this);
    if (name == u"legend")
        return new(std::nothrow) HTMLLegendElementImp(this);
    if (name == u"label")
        return new(std::nothrow) HTMLLabelElementImp(this);
    if (name == u"input")
        return new(std::nothrow) HTMLInputElementImp(this);
    if (name == u"button")
        return new(std::nothrow) HTMLButtonElementImp(this);
    if (name == u"select")
        return new(std::nothrow) HTMLSelectElementImp(this);
    if (name == u"datalist")
        return new(std::nothrow) HTMLDataListElementImp(this);
    if (name == u"optgroup")
        return new(std::nothrow) HTMLOptGroupElementImp(this);
    if (name == u"option")
        return new(std::nothrow) HTMLOptionElementImp(this);
    if (name == u"textarea")
        return new(std::nothrow) HTMLTextAreaElementImp(this);
    if (name == u"keygen")
        return new(std::nothrow) HTMLKeygenElementImp(this);
    if (name == u"output")
        return new(std::nothrow) HTMLOutputElementImp(this);
    if (name == u"progress")
        return new(std::nothrow) HTMLProgressElementImp(this);
    if (name == u"meter")
        return new(std::nothrow) HTMLMeterElementImp(this);
    if (name == u"details")
        return new(std::nothrow) HTMLDetailsElementImp(this);
    if (name == u"summary")
        return new(std::nothrow) HTMLElementImp(this, name);
    if (name == u"command")
        return new(std::nothrow) HTMLCommandElementImp(this);
    if (name == u"menu")
        return new(std::nothrow) HTMLMenuElementImp(this);

    if (name == u"binding")
        return new(std::nothrow) HTMLBindingElementImp(this);
    if (name == u"template")
        return new(std::nothrow) HTMLTemplateElementImp(this);
    if (name == u"implementation")
        return new(std::nothrow) HTMLScriptElementImp(this, name);

    // Deprecated elements
    if (name == u"center")   // shorthand for DIV align=center
        return new(std::nothrow) HTMLDivElementImp(this, name);
    if (name == u"font")
        return new(std::nothrow) HTMLFontElementImp(this);

    return new(std::nothrow) HTMLUnknownElementImp(this, name);
}

Element DocumentImp::createElementNS(const std::u16string& namespaceURI, const std::u16string& qualifiedName)
{
    std::u16string prefix;
    std::u16string localName;
    size_t pos = qualifiedName.find(u':');
    if (pos != std::u16string::npos) {
        prefix = qualifiedName.substr(0, pos);
        localName = qualifiedName.substr(pos + 1);
    } else
        localName = qualifiedName;
    // TODO: several more checks
    return new(std::nothrow) ElementImp(this, localName, namespaceURI, prefix);
}

DocumentFragment DocumentImp::createDocumentFragment()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Text DocumentImp::createTextNode(const std::u16string& data)
{
    return new(std::nothrow) TextImp(this, data);
}

Comment DocumentImp::createComment(const std::u16string& data)
{
    return new(std::nothrow) CommentImp(this, data);
}

ProcessingInstruction DocumentImp::createProcessingInstruction(const std::u16string& target, const std::u16string& data)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Node DocumentImp::importNode(Node node, bool deep)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Node DocumentImp::adoptNode(Node node)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

events::Event DocumentImp::createEvent(const std::u16string& interface)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::Location DocumentImp::getLocation()
{
    if (!defaultView)
        return 0;
    return new(std::nothrow) LocationImp(defaultView, url);
}

void DocumentImp::setLocation(const std::u16string& href)
{
    if (defaultView)
        defaultView->setLocation(href);
}

std::u16string DocumentImp::getURL()
{
    return url;
}

std::u16string DocumentImp::getDomain()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setDomain(const std::u16string& domain)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getReferrer()
{
    // TODO: implement me!
    return u"";
}

std::u16string DocumentImp::getCookie()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setCookie(const std::u16string& cookie)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getLastModified()
{
    // TODO: implement me!
    return u"";
}

std::u16string DocumentImp::getCharset()
{
    return charset;
}

void DocumentImp::setCharset(const std::u16string& charset)
{
    if (this->charset.empty()) {
        this->charset = charset;
        return;
    }
    // TODO: Change the  character encoding.
}

std::u16string DocumentImp::getCharacterSet()
{
    return  charset;
}

std::u16string DocumentImp::getDefaultCharset()
{
    // TODO: implement me!
    return u"";
}

std::u16string DocumentImp::getReadyState()
{
    return readyState;
}

Any DocumentImp::getElement(const std::u16string& name)
{
    Element e = getDocumentElement();
    if (!e)
        return 0;
    ElementImp* i = dynamic_cast<ElementImp*>(e.self());
    if (!i)
        return 0;
    HTMLCollectionImp* collection = new(std::nothrow) HTMLCollectionImp;
    if (!collection)
        return 0;
    std::u16string tag;
    while (i) {
        tag = i->getTagName();
        // TODO: check applet, embed, and object, too.
        if (tag == u"form" || tag == u"iframe" || tag == u"img") {
            Nullable<std::u16string> n = i->getAttribute(u"name");
            if (n.hasValue() && name == n.value())
                collection->addItem(name, i);
        }
        i = i->getNextElement();
    }
    switch (collection->getLength()) {
    case 0:
        delete collection;
        return 0;
    case 1:
        e = collection->item(0);
        delete collection;
        if (tag == u"iframe")
            return interface_cast<html::HTMLIFrameElement>(e).getContentWindow();
        else
            return e;
    default:
        return collection;
    }
}

std::u16string DocumentImp::getTitle()
{
    html::HTMLHeadElement head = getHead();
    if (!head)
        return u"";
    for (auto i = head.getFirstElementChild(); i; i = i.getNextElementSibling()) {
        if (i.getTagName() == u"title") {
            html::HTMLTitleElement t(interface_cast<html::HTMLTitleElement>(i));
            std::u16string title = t.getText();
            size_t spacePos;
            size_t spaceLen = 0;
            for (size_t i = 0; i < title.length(); ++i) {
                char16_t c = title[i];
                if (isSpace(c)) {
                    c = title[i] = ' ';
                    if (spaceLen == 0)
                        spacePos = i;
                    ++spaceLen;
                } else if (0 < spaceLen) {
                    if (1 < spaceLen) {
                        ++spacePos;
                        --spaceLen;
                        title.erase(spacePos, spaceLen);
                        i = spacePos;
                    }
                    spaceLen = 0;
                }
            }
            return title;
        }
    }
    return u"";
}

void DocumentImp::setTitle(const std::u16string& title)
{
    html::HTMLHeadElement head = getHead();
    if (!head)
        return;
    for (auto i = head.getFirstElementChild(); i; i = i.getNextElementSibling()) {
        if (i.getTagName() == u"title") {
            html::HTMLTitleElement t(interface_cast<html::HTMLTitleElement>(i));
            t.setText(title);
            return;
        }
    }
    if (html::HTMLTitleElement t = interface_cast<html::HTMLTitleElement>(createElement(u"title"))) {
        t.setText(title);
        head.appendChild(t);
    }
}

std::u16string DocumentImp::getDir()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setDir(const std::u16string& dir)
{
    // TODO: implement me!
}

html::HTMLElement DocumentImp::getBody()
{
    // TODO: refine.
    Element e = getDocumentElement();
    for (auto i = e.getFirstElementChild(); i; i = i.getNextElementSibling()) {
        if (i.getTagName() == u"body")
            return interface_cast<html::HTMLElement>(i);
    }
    return 0;
}

void DocumentImp::setBody(html::HTMLElement body)
{
    // TODO: implement me!
}

html::HTMLHeadElement DocumentImp::getHead()
{
    // TODO: refine.
    Element e = getDocumentElement();
    for (auto i = e.getFirstElementChild(); i; i = i.getNextElementSibling()) {
        if (i.getTagName() == u"head")
            return interface_cast<html::HTMLHeadElement>(i);
    }
    return 0;
}

html::HTMLCollection DocumentImp::getImages()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getEmbeds()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getPlugins()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getLinks()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getForms()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getScripts()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList DocumentImp::getElementsByName(const std::u16string& elementName)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

DOMElementMap DocumentImp::getCssElementMap()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

std::u16string DocumentImp::getInnerHTML()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setInnerHTML(const std::u16string& innerHTML)
{
    // TODO: implement me!
}

html::HTMLDocument DocumentImp::open(const std::u16string& type, const std::u16string& replace)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::Window DocumentImp::open(const std::u16string& url, const std::u16string& name, const std::u16string& features, bool replace)
{
    if (defaultView)
        return defaultView->open(url, name, features, replace);
    return static_cast<Object*>(0);
}

void DocumentImp::close()
{
    // TODO: implement me!
}

void DocumentImp::write(Variadic<std::u16string> text)
{
    // TODO: implement me!
}

void DocumentImp::writeln(Variadic<std::u16string> text)
{
    // TODO: implement me!
}

html::Window DocumentImp::getDefaultView()
{
    return defaultView;
}

Element DocumentImp::getActiveElement()
{
    if (activeElement)
        return activeElement;
    return getBody();
}

bool DocumentImp::hasFocus()
{
    // TODO: implement me!
    return 0;
}

std::u16string DocumentImp::getDesignMode()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setDesignMode(const std::u16string& designMode)
{
    // TODO: implement me!
}

bool DocumentImp::execCommand(const std::u16string& commandId)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::execCommand(const std::u16string& commandId, bool showUI)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::execCommand(const std::u16string& commandId, bool showUI, const std::u16string& value)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::queryCommandEnabled(const std::u16string& commandId)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::queryCommandIndeterm(const std::u16string& commandId)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::queryCommandState(const std::u16string& commandId)
{
    // TODO: implement me!
    return 0;
}

bool DocumentImp::queryCommandSupported(const std::u16string& commandId)
{
    // TODO: implement me!
    return 0;
}

std::u16string DocumentImp::queryCommandValue(const std::u16string& commandId)
{
    // TODO: implement me!
    return u"";
}

html::HTMLCollection DocumentImp::getCommands()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::Function DocumentImp::getOnabort()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnabort(html::Function onabort)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnblur()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnblur(html::Function onblur)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOncanplay()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOncanplay(html::Function oncanplay)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOncanplaythrough()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOncanplaythrough(html::Function oncanplaythrough)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnchange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnchange(html::Function onchange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnclick()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnclick(html::Function onclick)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOncontextmenu()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOncontextmenu(html::Function oncontextmenu)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOncuechange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOncuechange(html::Function oncuechange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndblclick()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndblclick(html::Function ondblclick)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndrag()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndrag(html::Function ondrag)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndragend()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndragend(html::Function ondragend)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndragenter()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndragenter(html::Function ondragenter)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndragleave()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndragleave(html::Function ondragleave)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndragover()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndragover(html::Function ondragover)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndragstart()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndragstart(html::Function ondragstart)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndrop()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndrop(html::Function ondrop)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOndurationchange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOndurationchange(html::Function ondurationchange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnemptied()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnemptied(html::Function onemptied)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnended()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnended(html::Function onended)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnerror()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnerror(html::Function onerror)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnfocus()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnfocus(html::Function onfocus)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOninput()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOninput(html::Function oninput)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOninvalid()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOninvalid(html::Function oninvalid)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnkeydown()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnkeydown(html::Function onkeydown)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnkeypress()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnkeypress(html::Function onkeypress)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnkeyup()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnkeyup(html::Function onkeyup)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnload()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnload(html::Function onload)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnloadeddata()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnloadeddata(html::Function onloadeddata)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnloadedmetadata()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnloadedmetadata(html::Function onloadedmetadata)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnloadstart()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnloadstart(html::Function onloadstart)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmousedown()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmousedown(html::Function onmousedown)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmousemove()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmousemove(html::Function onmousemove)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmouseout()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmouseout(html::Function onmouseout)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmouseover()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmouseover(html::Function onmouseover)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmouseup()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmouseup(html::Function onmouseup)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnmousewheel()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnmousewheel(html::Function onmousewheel)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnpause()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnpause(html::Function onpause)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnplay()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnplay(html::Function onplay)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnplaying()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnplaying(html::Function onplaying)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnprogress()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnprogress(html::Function onprogress)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnratechange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnratechange(html::Function onratechange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnreadystatechange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnreadystatechange(html::Function onreadystatechange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnreset()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnreset(html::Function onreset)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnscroll()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnscroll(html::Function onscroll)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnseeked()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnseeked(html::Function onseeked)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnseeking()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnseeking(html::Function onseeking)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnselect()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnselect(html::Function onselect)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnshow()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnshow(html::Function onshow)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnstalled()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnstalled(html::Function onstalled)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnsubmit()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnsubmit(html::Function onsubmit)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnsuspend()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnsuspend(html::Function onsuspend)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOntimeupdate()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOntimeupdate(html::Function ontimeupdate)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnvolumechange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnvolumechange(html::Function onvolumechange)
{
    // TODO: implement me!
}

html::Function DocumentImp::getOnwaiting()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::setOnwaiting(html::Function onwaiting)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getFgColor()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setFgColor(const std::u16string& fgColor)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getBgColor()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setBgColor(const std::u16string& bgColor)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getLinkColor()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setLinkColor(const std::u16string& linkColor)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getVlinkColor()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setVlinkColor(const std::u16string& vlinkColor)
{
    // TODO: implement me!
}

std::u16string DocumentImp::getAlinkColor()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setAlinkColor(const std::u16string& alinkColor)
{
    // TODO: implement me!
}

html::HTMLCollection DocumentImp::getAnchors()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getApplets()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::clear()
{
    // TODO: implement me!
}

html::HTMLAllCollection DocumentImp::getAll()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

css::CSSStyleDeclaration DocumentImp::getOverrideStyle(Element elt, Nullable<std::u16string> pseudoElt)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

stylesheets::StyleSheetList DocumentImp::getStyleSheets()
{
    return new(std::nothrow) ObjectArrayImp<DocumentImp, stylesheets::StyleSheet, &DocumentImp::styleSheets>(this);
}

Nullable<std::u16string> DocumentImp::getSelectedStyleSheetSet()
{
    // TODO: implement me!
    return u"";
}

void DocumentImp::setSelectedStyleSheetSet(Nullable<std::u16string> selectedStyleSheetSet)
{
    // TODO: implement me!
}

Nullable<std::u16string> DocumentImp::getLastStyleSheetSet()
{
    // TODO: implement me!
    return u"";
}

Nullable<std::u16string> DocumentImp::getPreferredStyleSheetSet()
{
    // TODO: implement me!
    return u"";
}

DOMStringList DocumentImp::getStyleSheetSets()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

void DocumentImp::enableStyleSheetsForSet(Nullable<std::u16string> name)
{
    // TODO: implement me!
}

Element DocumentImp::elementFromPoint(float x, float y)
{
    if (!defaultView)
        return 0;
    return defaultView->elementFromPoint(x, y);
}

CaretPosition DocumentImp::caretPositionFromPoint(float x, float y)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Element DocumentImp::querySelector(const std::u16string& selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

NodeList DocumentImp::querySelectorAll(const std::u16string& selectors)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

ranges::Range DocumentImp::createRange()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

traversal::NodeIterator DocumentImp::createNodeIterator(Node root, unsigned int whatToShow, traversal::NodeFilter filter, bool entityReferenceExpansion) throw(DOMException)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

traversal::TreeWalker DocumentImp::createTreeWalker(Node root, unsigned int whatToShow, traversal::NodeFilter filter, bool entityReferenceExpansion) throw(DOMException)
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

html::HTMLCollection DocumentImp::getBindingDocuments()
{
    // TODO: implement me!
    return static_cast<Object*>(0);
}

Document DocumentImp::loadBindingDocument(const std::u16string& documentURI)
{
    auto found = bindingDocuments.find(documentURI);
    if (found != bindingDocuments.end())
        return found->second.getDocument();

    WindowImp* window = new WindowImp(defaultView);
    if (!window)
        return 0;
    bindingDocuments.insert(std::pair<std::u16string, html::Window>(documentURI, window));
    window->open(documentURI, u"_self", u"", true);
    return window->getDocument();
}

bool DocumentImp::isBindingDocumentWindow(const WindowImp* window) const
{
    for (auto i = bindingDocuments.begin(); i != bindingDocuments.end(); ++i) {
        if (i->second.self() == window)
            return true;
    }
    return false;
}

// Node - override

unsigned short DocumentImp::getNodeType()
{
    return Node::DOCUMENT_NODE;
}

Node DocumentImp::appendChild(Node newChild) throw(DOMException)
{
    if (DocumentTypeImp* newDoctype = dynamic_cast<DocumentTypeImp*>(newChild.self())) {
        if (getDoctype())
            throw DOMException{DOMException::HIERARCHY_REQUEST_ERR};
        if (!newChild.getOwnerDocument())
            newDoctype->setOwnerDocument(this);
        NodeImp::appendChild(newChild);
        doctype = newDoctype;
        return newChild;
    }
    // TODO: check second Element
    return NodeImp::appendChild(newChild);
}

}}}}  // org::w3c::dom::bootstrap

max_stars_repo_name: rvedam/es-operating-system

max_issues_repo_name: LambdaLord/es-operating-system

max_forks_repo_name: LambdaLord/es-operating-system


text:
#pragma once

#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>

#include <cryptopp/osrng.h>
#include <blake2/blake2.h>

using Rational = boost::rational<boost::multiprecision::int256_t>;
using Reward   = std::pair<boost::multiprecision::uint128_t, Rational>;

namespace logos
{
// Random pool used by Logos.
// This must be thread_local as long as the AutoSeededRandomPool implementation requires it
extern thread_local CryptoPP::AutoSeededRandomPool random_pool;
using uint128_t = boost::multiprecision::uint128_t;
using uint256_t = boost::multiprecision::uint256_t;
using uint512_t = boost::multiprecision::uint512_t;
// SI dividers
logos::uint128_t const Glgs_ratio = logos::uint128_t ("1000000000000000000000000000000000"); // 10^33
logos::uint128_t const Mlgs_ratio = logos::uint128_t ("1000000000000000000000000000000"); // 10^30
logos::uint128_t const klgs_ratio = logos::uint128_t ("1000000000000000000000000000"); // 10^27
logos::uint128_t const lgs_ratio = logos::uint128_t ("1000000000000000000000000"); // 10^24
logos::uint128_t const mlgs_ratio = logos::uint128_t ("1000000000000000000000"); // 10^21
logos::uint128_t const ulgs_ratio = logos::uint128_t ("1000000000000000000"); // 10^18

// We operate on streams of uint8_t by convention
using stream = std::basic_streambuf<uint8_t>;

class mdb_val;

union uint128_union
{
public:
    static_assert (sizeof(uint128_t)==16, "sizeof(uint128_t) != 16");

    uint128_union ()
    {
        memset(bytes.data(), 0, 16);
    }
    uint128_union (std::string const &);
    uint128_union (uint64_t);
    uint128_union (logos::uint128_union const &) = default;
    uint128_union (logos::uint128_t const &);
    bool Deserialize(logos::stream & stream);
    uint32_t Serialize(logos::stream & stream) const;
    uint128_union operator+ (logos::uint128_union const &) const;
    uint128_union operator- (logos::uint128_union const &) const;
    uint128_union operator* (logos::uint128_union const &) const;
    bool operator== (logos::uint128_union const &) const;
    bool operator!= (logos::uint128_union const &) const;
    bool operator< (logos::uint128_union const &) const;
    bool operator> (logos::uint128_union const &) const;
    bool operator<= (logos::uint128_union const &) const;
    bool operator>= (logos::uint128_union const &) const;
    uint128_union & operator+=(const uint128_union & other);
    uint128_union & operator-=(const uint128_union & other);
    void encode_hex (std::string &) const;
    bool decode_hex (std::string const &);
    void encode_dec (std::string &) const;
    bool decode_dec (std::string const &);
    std::string format_balance (logos::uint128_t scale, int precision, bool group_digits);
    std::string format_balance (logos::uint128_t scale, int precision, bool group_digits, const std::locale & locale);
    logos::uint128_t number () const;
    void clear ();
    bool is_zero () const;
    std::string to_string () const;
    std::string to_string_dec () const;
    logos::mdb_val to_mdb_val(std::vector<uint8_t>& buf) const;
    std::array<uint8_t, 16> bytes;
    std::array<char, 16> chars;
    std::array<uint32_t, 4> dwords;
    std::array<uint64_t, 2> qwords;

    const uint8_t * data() const
    {
        return bytes.data();
    }
    void Hash(blake2b_state & hash) const
    {
        blake2b_update(&hash, bytes.data(), 16);
    }

    operator std::array<uint8_t, 16>() { return bytes; }
};
// Balances are 128 bit.
using amount = uint128_union;
class raw_key;
union uint256_union
{
    uint256_union ()
    {
        memset(bytes.data(), 0, 32);
    }
    uint256_union (std::string const &);
    uint256_union (uint64_t);
    uint256_union (logos::uint256_t const &);
    uint256_union (std::array<uint8_t, 32> const &);
    void encrypt (logos::raw_key const &, logos::raw_key const &, uint128_union const &);
    uint256_union & operator^= (logos::uint256_union const &);
    uint256_union operator^ (logos::uint256_union const &) const;
    bool operator== (logos::uint256_union const &) const;
    bool operator!= (logos::uint256_union const &) const;
    bool operator< (logos::uint256_union const &) const;
    uint256_union operator+ (logos::uint256_union const &) const;
    uint256_union operator- (logos::uint256_union const &) const;
    void encode_hex (std::string &) const;
    bool decode_hex (std::string const &);
    void encode_dec (std::string &) const;
    bool decode_dec (std::string const &);
    void encode_account (std::string &) const;
    std::string to_account () const;
    std::string to_account_split () const;
    bool decode_account (std::string const &);
    std::array<uint8_t, 32> bytes;
    std::array<char, 32> chars;
    std::array<uint32_t, 8> dwords;
    std::array<uint64_t, 4> qwords;
    std::array<uint128_union, 2> owords;
    void clear ();
    bool is_zero () const;
    std::string to_string () const;
    logos::uint256_t number () const;

    uint8_t * data()
    {
        return bytes.data();
    }

    const uint8_t * data() const
    {
        return bytes.data();
    }

    void Hash(blake2b_state & hash) const
    {
        blake2b_update(&hash, bytes.data(), 32);
    }
    uint256_union(void * buf, size_t buf_len)
    {
        assert(buf_len == 32);
        memcpy(data(), buf, 32);
    }

    operator std::array<uint8_t, 32>() { return bytes; }
};
// All keys and hashes are 256 bit.
using block_hash = uint256_union;
using account = uint256_union;
using public_key = uint256_union;
using private_key = uint256_union;
using secret_key = uint256_union;
using checksum = uint256_union;
class raw_key
{
public:
    raw_key () = default;
    ~raw_key ();
    void decrypt (logos::uint256_union const &, logos::raw_key const &, uint128_union const &);
    raw_key (logos::raw_key const &) = delete;
    raw_key (logos::raw_key const &&) = delete;
    logos::raw_key & operator= (logos::raw_key const &) = delete;
    bool operator== (logos::raw_key const &) const;
    bool operator!= (logos::raw_key const &) const;
    logos::uint256_union data;
};
union uint512_union
{
    uint512_union (uint8_t t = 0)
    {
        memset(bytes.data(), t, 64);
    }

    uint512_union (logos::uint512_t const &);
    bool operator== (logos::uint512_union const &) const;
    bool operator!= (logos::uint512_union const &) const;
    logos::uint512_union & operator^= (logos::uint512_union const &);
    void encode_hex (std::string &) const;
    bool decode_hex (std::string const &);
    std::array<uint8_t, 64> bytes;
    std::array<uint32_t, 16> dwords;
    std::array<uint64_t, 8> qwords;
    std::array<uint256_union, 2> uint256s;
    void clear ();
    logos::uint512_t number () const;
    std::string to_string () const;

    uint8_t * data()
    {
        return bytes.data();
    }

    const uint8_t * data() const
    {
        return bytes.data();
    }

    void Hash(blake2b_state & hash) const
    {
        blake2b_update(&hash, bytes.data(), 64);
    }

    operator std::array<uint8_t, 64>() { return bytes; }
};
// Only signatures are 512 bit.
using signature = uint512_union;

logos::uint512_union sign_message (logos::raw_key const &, logos::public_key const &, logos::uint256_union const &);
bool validate_message (logos::public_key const &, logos::uint256_union const &, logos::uint512_union const &);
void deterministic_key (logos::uint256_union const &, uint32_t, logos::uint256_union &);
}

namespace std
{
template <>
struct hash<logos::uint256_union>
{
    size_t operator() (logos::uint256_union const & data_a) const
    {
        return *reinterpret_cast<size_t const *> (data_a.bytes.data ());
    }
};
template <>
struct hash<logos::uint256_t>
{
    size_t operator() (logos::uint256_t const & number_a) const
    {
        return number_a.convert_to<size_t> ();
    }
};
}

namespace logos
{

inline
size_t hash_value(const logos::block_hash & hash)
{
    return std::hash<logos::block_hash>()(hash);
}

}

ext: hpp

max_stars_repo_name: LogosNetwork/logos-core

max_issues_repo_name: LogosNetwork/logos-core

max_forks_repo_name: LogosNetwork/logos-core


text:
// Copyright 2020 Advanced Remanufacturing and Technology Centre
// Copyright 2020 ROS-Industrial Consortium Asia Pacific Team
//
// 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 "gui/addrobot.h"

#include <boost/filesystem.hpp>
#include <QKeyEvent>
#include <iostream>
#include <sstream>
#include <string>

#include "gui/ui_addrobot.h"

AddRobot::AddRobot(QWidget * parent)
: QDialog(parent),
  ui(new Ui::AddRobot)
{
  ui->setupUi(this);
  on_include_origin_stateChanged(0);
  success = false;
}

AddRobot::~AddRobot()
{
  boost::filesystem::current_path(original_path);
  delete ui;
}
void AddRobot::LoadExistingRobot(Robot robot_input)
{
  robot = robot_input;
  // Populate Origin
  if (robot.origin.is_origin) {
    ui->include_origin->setChecked(true);
    on_include_origin_stateChanged(2);
    if (robot.origin.x >= 0) {ui->x_2->setText(QString::number(robot.origin.x));}
    if (robot.origin.y >= 0) {ui->y_2->setText(QString::number(robot.origin.y));}
    if (robot.origin.z >= 0) {ui->z_2->setText(QString::number(robot.origin.z));}
    if (robot.origin.roll >= 0) {ui->roll_2->setText(QString::number(robot.origin.roll));}
    if (robot.origin.pitch >= 0) {ui->pitch_2->setText(QString::number(robot.origin.pitch));}
    if (robot.origin.yaw >= 0) {ui->yaw_2->setText(QString::number(robot.origin.yaw));}
  } else {
    ui->include_origin->stateChanged(0);
  }

  // Populate Brand
  for (int brand = 0; brand < static_cast<int>(available_brands.size()); brand++) {
    if (robot.brand.compare(available_brands[brand]) == 0) {
      ui->robot_brand->setCurrentIndex(brand);
      for (int model = 0; model < static_cast<int>(available_robots[brand].size()); model++) {
        if (robot.name.compare(available_robots[brand][model].name) == 0) {
          ui->robot_model->setCurrentIndex(model);
          for (int link = 0; link <
            static_cast<int>(available_robots[brand][model].robot_links.size());
            link++)
          {
            if (robot.base_link.compare(available_robots[brand][model].robot_links[link]) == 0) {
              ui->robot_links->setCurrentIndex(link);
            }
            if (robot.ee_link.compare(available_robots[brand][model].robot_links[link]) == 0) {
              ui->robot_ee_link->setCurrentIndex(link);
            }
          }
          break;
        }
      }
      break;
    }
  }
}

int AddRobot::LoadAvailableRobots()
{
  original_path = boost::filesystem::current_path();
  boost::filesystem::current_path(boost::filesystem::current_path().branch_path());  //
  boost::filesystem::current_path("assets");
  boost::filesystem::current_path("robots");
  available_brands.clear();
  available_robots.clear();
  if (boost::filesystem::is_empty(boost::filesystem::current_path())) {
    return 0;
  } else {
    boost::filesystem::path temp_path(boost::filesystem::current_path());
    for (auto & filepath :
      boost::filesystem::directory_iterator(boost::filesystem::current_path()))
    {
      std::string temp_brand;
      std::vector<Robot> brand_robot_vector;
      for (auto it = filepath.path().string().crbegin(); it != filepath.path().string().crend();
        ++it)
      {
        if (*it != '/') {
          temp_brand = std::string(1, *it) + temp_brand;
        } else {
          boost::filesystem::current_path(temp_brand);
          if (temp_brand.compare("universal_robot") == 0) {
            std::vector<std::string> valid_robots;
            for (auto & filepath :
              boost::filesystem::directory_iterator(boost::filesystem::current_path()))
            {
              std::string temp_model;
              bool is_moveit = false;
              int char_count = 0;
              for (auto it = filepath.path().string().crbegin();
                it != filepath.path().string().crend(); ++it)
              {
                if (*it != '/') {
                  temp_model = std::string(1, *it) + temp_model;
                  char_count++;
                  if (char_count == 13) {
                    if (temp_model.compare("moveit_config") == 0) {
                      is_moveit = true;
                    }
                  }
                }
                if (*it == '/') {
                  break;
                }
              }
              if (is_moveit) {
                valid_robots.push_back(temp_model.substr(0, temp_model.size() - 14));
              }
            }
            brand_robot_vector = LoadUR(valid_robots);
          } else {
            std::vector<std::string> moveit_configs;
            std::vector<std::string> descriptions;
            for (auto & filepath :
              boost::filesystem::directory_iterator(boost::filesystem::current_path()))
            {
              bool is_description = false;
              bool is_moveit = false;

              std::string temp_model;
              int char_count = 0;
              // Only _descrtiption
              for (auto it = filepath.path().string().crbegin();
                it != filepath.path().string().crend(); ++it)
              {
                if (*it != '/') {
                  temp_model = std::string(1, *it) + temp_model;
                  char_count++;
                  if (char_count == 11) {
                    if (temp_model.compare("description") == 0) {
                      is_description = true;
                    }
                  }
                  if (char_count == 13) {
                    if (temp_model.compare("moveit_config") == 0) {
                      is_moveit = true;
                    }
                  }
                } else {
                  break;
                }
              }

              if (is_description) {
                descriptions.push_back(temp_model.substr(0, temp_model.size() - 12));
              }
              if (is_moveit) {
                moveit_configs.push_back(temp_model.substr(0, temp_model.size() - 14));
              }
            }
            boost::filesystem::current_path(boost::filesystem::current_path().branch_path());

            if (moveit_configs.size() < descriptions.size()) {
              for (int i = 0; i < static_cast<int>(descriptions.size()); i++) {
                if (std::find(
                    moveit_configs.begin(), moveit_configs.end(),
                    descriptions[i]) != moveit_configs.end())
                {
                  brand_robot_vector.push_back(
                    LoadRobot(
                      descriptions[i] + "_description",
                      temp_brand));
                }
              }
            } else {
              for (int i = 0; i < static_cast<int>(moveit_configs.size()); i++) {
                if (std::find(
                    descriptions.begin(), descriptions.end(),
                    moveit_configs[i]) != descriptions.end())
                {
                  brand_robot_vector.push_back(
                    LoadRobot(
                      moveit_configs[i] + "_description",
                      temp_brand));
                }
              }
            }
          }
          break;
        }
      }
      if (!brand_robot_vector.empty()) {
        available_robots.push_back(brand_robot_vector);
        available_brands.push_back(temp_brand);
      }
      boost::filesystem::current_path(temp_path);
    }
    for (int i3 = 0; i3 < static_cast<int>(available_brands.size()); i3++) {
      ui->robot_brand->addItem(QString::fromStdString(available_brands[i3]));
    }

    ui->robot_brand->setCurrentIndex(0);
    on_robot_brand_currentIndexChanged(0);
    ui->robot_model->setCurrentText(0);
    on_robot_model_currentIndexChanged(0);
    ui->robot_links->setCurrentIndex(0);
    ui->robot_ee_link->setCurrentIndex(0);
    int total_count = 0;
    for (int i = 0; i < static_cast<int>(available_brands.size()); i++) {
      for (int i2 = 0; i2 < static_cast<int>(available_robots[i].size()); i2++) {
        total_count++;
      }
    }
    return total_count;
  }
  return 0;
}

Robot AddRobot::LoadRobot(std::string file, std::string brand)
{
  boost::filesystem::path temp_path(boost::filesystem::current_path());
  Robot temp_robot;
  temp_robot.filepath = boost::filesystem::current_path().string() + "/" + file;
  boost::filesystem::current_path(brand);
  boost::filesystem::current_path(file);
  boost::filesystem::current_path("urdf");
  temp_robot.brand = brand;
  temp_robot.name = file.erase(file.length() - 12);
  temp_robot.robot_links = GetLinks(temp_robot.name + ".urdf.xacro");
  boost::filesystem::current_path(temp_path);
  return temp_robot;
}

std::vector<Robot> AddRobot::LoadUR(std::vector<std::string> robot_list)
// load ur robots based on the way it is structured
{
  boost::filesystem::current_path("ur_description");
  boost::filesystem::current_path("urdf");

  std::vector<Robot> ur_robot_vector;
  for (int i = 0; i < static_cast<int>(robot_list.size()); i++) {
    Robot temp_robot;
    temp_robot.brand = "universal_robot";
    temp_robot.name = robot_list[i];
    temp_robot.robot_links = GetLinks(temp_robot.name + ".urdf.xacro");
    ur_robot_vector.push_back(temp_robot);
  }
  return ur_robot_vector;
}

std::vector<std::string> AddRobot::GetLinks(std::string filename)
{
  std::vector<std::string> links;

  std::ifstream infile(filename);
  std::string line;
  while (std::getline(infile, line)) {
    std::istringstream ss(line);
    ss >> std::ws;
    std::string temp_string;
    temp_string.resize(11);
    ss.read(&temp_string[0], 11);
    if (temp_string.compare("<link name=") == 0) {
      remove_if(line.begin(), line.end(), isspace);
      line.erase(0, line.find("\"") + 1);
      line.erase(line.begin() + line.find("\""), line.end());
      line.erase(0, line.find("}") + 1);
      links.push_back(line);
    }
  }
  return links;
}

void AddRobot::on_robot_brand_currentIndexChanged(int index)
{
  bool oldState = ui->robot_model->blockSignals(true);
  ui->robot_model->clear();
  for (int i = 0; i < static_cast<int>(available_robots[index].size()); i++) {
    ui->robot_model->addItem(QString::fromStdString(available_robots[index][i].name));
  }
  ui->robot_model->blockSignals(oldState);
  ui->robot_model->setCurrentIndex(0);
  on_robot_model_currentIndexChanged(0);
}

void AddRobot::on_robot_model_currentIndexChanged(int index)
{
  bool oldState = ui->robot_links->blockSignals(true);
  bool oldState2 = ui->robot_ee_link->blockSignals(true);
  ui->robot_links->clear();
  ui->robot_ee_link->clear();
  for (int i = 0;
    i <
    static_cast<int>(available_robots[ui->robot_brand->currentIndex()][ui->robot_model->currentIndex()  // NOLINT
    ].
    robot_links
    .size()); i++)
  {
    ui->robot_links->addItem(
      QString::fromStdString(
        available_robots[ui->robot_brand->currentIndex()
        ][index].robot_links[i]));
    ui->robot_ee_link->addItem(
      QString::fromStdString(
        available_robots[ui->robot_brand->currentIndex()
        ][index].robot_links[i]));
  }
  ui->robot_links->blockSignals(oldState);
  ui->robot_links->setCurrentIndex(0);
  ui->robot_ee_link->blockSignals(oldState2);
  ui->robot_ee_link->setCurrentIndex(0);
}

void AddRobot::on_include_origin_stateChanged(int arg1)
{
  if (arg1 == 0) {
    // No Origin
    ui->x_2->setDisabled(true);
    ui->x_2->setText(QString::fromStdString("0"));
    ui->x_label_2->setDisabled(true);
    ui->y_2->setDisabled(true);
    ui->y_2->setText(QString::fromStdString("0"));
    ui->y_label_2->setDisabled(true);
    ui->z_2->setDisabled(true);
    ui->z_2->setText(QString::fromStdString("0"));
    ui->z_label_2->setDisabled(true);
    ui->roll_2->setDisabled(true);
    ui->roll_2->setText(QString::fromStdString("0"));
    ui->roll_label_2->setDisabled(true);
    ui->pitch_2->setDisabled(true);
    ui->pitch_2->setText(QString::fromStdString("0"));
    ui->pitch_label_2->setDisabled(true);
    ui->yaw_2->setDisabled(true);
    ui->yaw_2->setText(QString::fromStdString("0"));
    ui->yaw_label_2->setDisabled(true);
    ui->origin_label_2->setDisabled(true);
    ui->position_label_2->setDisabled(true);
    ui->orientation_label_2->setDisabled(true);
  } else {
    // Have origin
    ui->x_2->setDisabled(false);
    ui->x_2->clear();
    ui->x_label_2->setDisabled(false);
    ui->y_2->setDisabled(false);
    ui->y_2->clear();
    ui->y_label_2->setDisabled(false);
    ui->z_2->setDisabled(false);
    ui->z_2->clear();
    ui->z_label_2->setDisabled(false);
    ui->roll_2->setDisabled(false);
    ui->roll_2->clear();
    ui->roll_label_2->setDisabled(false);
    ui->pitch_2->setDisabled(false);
    ui->pitch_2->clear();
    ui->pitch_label_2->setDisabled(false);
    ui->yaw_2->setDisabled(false);
    ui->yaw_2->clear();
    ui->yaw_label_2->setDisabled(false);
    ui->origin_label_2->setDisabled(false);
    ui->position_label_2->setDisabled(false);
    ui->orientation_label_2->setDisabled(false);
  }
}

void AddRobot::on_exit_2_clicked()
{
  success = false;
  this->close();
}

void AddRobot::on_ok_2_clicked()
{
  if (ui->robot_brand->currentIndex() < 0 || ui->robot_model->currentIndex() < 0) {
    ui->errorlist_2->append("  Invalid Robot Brand or Robot Model \n ");
  } else {
    robot = available_robots[ui->robot_brand->currentIndex()][ui->robot_model->currentIndex()];
    ui->errorlist_2->clear();
    if (ErrorCheckOrigin() == 0) {
      if (ui->robot_links->currentIndex() < 0) {
        ui->errorlist_2->append("  Invalid Base Link \n ");
        return;
      }
      if (ui->robot_ee_link->currentIndex() < 0) {
        ui->errorlist_2->append("  Invalid EE Link \n ");
        return;
      }
      robot.base_link = ui->robot_links->currentText().toStdString();
      robot.ee_link = ui->robot_ee_link->currentText().toStdString();
      success = true;
      this->close();
    }
  }
}

int AddRobot::ErrorCheckOrigin()
{
  int num_errors = 0;
  if (ui->include_origin->isChecked()) {
    robot.origin.is_origin = true;
    bool all_empty_xyz =
      (ui->x_2->text().isEmpty() && ui->y_2->text().isEmpty() && ui->z_2->text().isEmpty());
    bool all_full_xyz =
      (!ui->x_2->text().isEmpty() && !ui->y_2->text().isEmpty() && !ui->z_2->text().isEmpty());

    bool all_empty_rpy =
      (ui->roll_2->text().isEmpty() && ui->pitch_2->text().isEmpty() &&
      ui->yaw_2->text().isEmpty());
    bool all_full_rpy =
      (!ui->roll_2->text().isEmpty() && !ui->pitch_2->text().isEmpty() &&
      !ui->yaw_2->text().isEmpty());
    if (all_empty_rpy && all_empty_xyz) {
      ui->errorlist_2->append(
        "  All Origin Fields are empty."
        " Uncheck the Origin selection to disable the option. \n ");
      num_errors++;
    } else {
      if (!all_full_xyz && !all_empty_xyz) {
        ui->errorlist_2->append(
          " XYZ values not complete."
          " Leave it all blank for default values. \n ");
        num_errors++;
      } else {
        if (all_full_xyz) {
          int i = 0;
          auto float_validator = new QDoubleValidator();
          QString input_x = ui->x_2->text();
          QString input_y = ui->y_2->text();
          QString input_z = ui->z_2->text();
          if (float_validator->validate(
              input_x,
              i) != QValidator::Acceptable ||
            float_validator->validate(
              input_y,
              i) != QValidator::Acceptable ||
            float_validator->validate(input_z, i) != QValidator::Acceptable)
          {
            ui->errorlist_2->append(
              " Type Error: XYZ need to be floats \n ");
            num_errors++;
          } else {
            robot.origin.x = input_x.toFloat();
            robot.origin.y = input_y.toFloat();
            robot.origin.z = input_z.toFloat();
          }
        }
      }
      if (!all_full_rpy && !all_empty_rpy) {
        ui->errorlist_2->append(
          " RPY values not complete."
          " Leave it all blank for default values ");
        num_errors++;
      } else {
        if (all_full_rpy) {
          int i = 0;
          auto float_validator = new QDoubleValidator();
          QString input_roll = ui->roll_2->text();
          QString input_pitch = ui->pitch_2->text();
          QString input_yaw = ui->yaw_2->text();
          if (float_validator->validate(
              input_roll,
              i) != QValidator::Acceptable ||
            float_validator->validate(
              input_pitch,
              i) != QValidator::Acceptable ||
            float_validator->validate(input_yaw, i) != QValidator::Acceptable)
          {
            ui->errorlist_2->append(
              "  Type Error: RPY need"
              " to be floats ");
            num_errors++;
          } else {
            robot.origin.roll = ui->roll_2->text().toFloat();
            robot.origin.pitch = ui->pitch_2->text().toFloat();
            robot.origin.yaw = ui->yaw_2->text().toFloat();
          }
        }
      }
    }
  } else {
    robot.origin.disableOrigin();
  }
  return num_errors;
}

void AddRobot::keyPressEvent(QKeyEvent * e)
{
  if (e->key() != Qt::Key_Escape) {
    QDialog::keyPressEvent(e);
  } else { /* minimize */}
}

ext: cpp


text:
#define BOOST_TEST_MODULE
#include <boost/test/unit_test.hpp>
#include <util/test_macros.hpp>
#include <stdlib.h>
#include <vector>
#include <string>
#include <functional>

#include <random>

// ML-Data Utils
#include <ml_data/ml_data.hpp>

// Models
#include <unity/toolkits/supervised_learning/supervised_learning.hpp>
#include <unity/toolkits/supervised_learning/boosted_trees.hpp>

#include <sframe/testing_utils.hpp>
#include <util/testing_utils.hpp>

#include <cfenv>

using namespace turi;
using namespace turi::supervised;
using namespace turi::supervised::xgboost;

void run_boosted_trees_classifier_test(
    std::map<std::string, flexible_type> test_opts,
    std::map<std::string, flexible_type> model_opts = std::map<std::string, flexible_type>()) {

  size_t examples = test_opts.at("examples");
  size_t features = test_opts.at("features");
  std::string target_column_name = "target";
  std::vector<std::string> column_names = {"user", "item"};

  // Answers
  // -----------------------------------------------------------------------
  DenseVector coefs(features+1);
  coefs.setRandom();

  // Feature names
  std::vector<std::string> feature_names;
  std::vector<flex_type_enum> feature_types;
  for(size_t i=0; i < features; i++){
    feature_names.push_back(std::to_string(i));
    feature_types.push_back(flex_type_enum::FLOAT);
  }

  // Data
  std::vector<std::vector<flexible_type>> y_data;
  std::vector<std::vector<flexible_type>> X_data;
  for(size_t i=0; i < examples; i++){
    DenseVector x(features);
    x.setRandom();
    std::vector<flexible_type> x_tmp;
    for(size_t k=0; k < features; k++){
      x_tmp.push_back(x(k));
    }

    // Compute the prediction for this
    double t = x.dot(coefs.segment(0, features)) + coefs(features);
    t = 1.0/(1.0+exp(-1.0*t));
    int c = turi::random::bernoulli(t);
    std::vector<flexible_type> y_tmp;
    y_tmp.push_back(c);

    X_data.push_back(x_tmp);
    y_data.push_back(y_tmp);
  }

  // Options
  std::map<std::string, flexible_type> options = model_opts;

  // Make the data
  sframe X = make_testing_sframe(feature_names, feature_types, X_data);
  sframe y = make_testing_sframe({"target"}, {flex_type_enum::INTEGER}, y_data);

  // Train model
  std::shared_ptr<boosted_trees_classifier> model;
  model.reset(new boosted_trees_classifier);
  model->init(X,y);
  model->init_options(options);
  if (test_opts.count("external_memory")) {
    model->_set_storage_mode(storage_mode_enum::EXT_MEMORY);
    model->_set_num_batches(8);
  }
  model->train();

  // Check options
  // ----------------------------------------------------------------------
  std::map<std::string, flexible_type> _options;
  _options = model->get_current_options();
  for (auto& kvp: options){
    TS_ASSERT(_options[kvp.first] == kvp.second);
  }
  TS_ASSERT(model->is_trained() == true);

  // Check predictions
  // ----------------------------------------------------------------------

  // Construct the ml_data
  ml_data data = model->construct_ml_data_using_current_metadata(X, y);

  std::vector<flexible_type> pred_class;
  std::shared_ptr<sarray<flexible_type>> _pred_class
    = model->predict(data, "class");

  // Check that we can train a model when providing a validation set
  std::vector<std::vector<flexible_type>> y_v;
  std::vector<std::vector<flexible_type>> X_v;
  for(size_t i=0; i < 5; i++){
    DenseVector x(features);
    x.setRandom();
    std::vector<flexible_type> x_tmp;
    for(size_t k=0; k < features; k++){
      x_tmp.push_back(x(k));
    }

    // Compute the prediction for this
    double t = x.dot(coefs.segment(0, features)) + coefs(features);
    t = 1.0/(1.0+exp(-1.0*t));
    int c = turi::random::bernoulli(t);
    std::vector<flexible_type> y_tmp;
    y_tmp.push_back(1 + c);

    X_v.push_back(x_tmp);
    y_v.push_back(y_tmp);
  }

  sframe Xv = make_testing_sframe(feature_names, feature_types, X_v);
  sframe yv = make_testing_sframe({"target"}, {flex_type_enum::INTEGER}, y_v);

  model.reset(new boosted_trees_classifier);
  model->init(X, y, Xv, yv);
  model->init_options(options);
  if (test_opts.count("external_memory")) {
    model->_set_storage_mode(storage_mode_enum::EXT_MEMORY);
    model->_set_num_batches(8);
  }

  model->train();

  ml_data valid_data = model->construct_ml_data_using_current_metadata(Xv, yv);
  auto ret = model->evaluate(valid_data, "accuracy");
  for (auto kv : ret) {
    logprogress_stream << kv.first << ": "
                       << variant_get_value<flexible_type>(kv.second)
                       << std::endl;
  }
  ret = model->evaluate(valid_data, "rmse");
  for (auto kv : ret) {
    logprogress_stream << kv.first << ": "
                       << variant_get_value<flexible_type>(kv.second)
                       << std::endl;
  }
}

struct boosted_trees_classifier_test  {
  public:
  void test_boosted_trees_classifier_basic_2d() {
    std::map<std::string, flexible_type> opts = {
      {"examples", 100},
      {"features", 1}};
    run_boosted_trees_classifier_test(opts);
  }

  void test_boosted_trees_classifier_small() {
    std::map<std::string, flexible_type> opts = {
      {"examples", 1000},
      {"features", 10}};
    run_boosted_trees_classifier_test(opts);
  }

  void test_boosted_trees_classifier_with_insufficient_column_subsample() {
    std::map<std::string, flexible_type> opts = {
      {"examples", 1000},
      {"features", 10}
    };
    std::map<std::string, flexible_type> model_opts = {
      {"column_subsample", 0.01}
    };
    run_boosted_trees_classifier_test(opts, model_opts);
  }

  void test_boosted_trees_classifier_external_memory() {
    std::map<std::string, flexible_type> opts = {
      {"examples", 1000},
      {"features", 10},
      {"external_memory", 1},
      {"row_subsample", .5},
      {"column_subsample", .5},
    };
    run_boosted_trees_classifier_test(opts);
  }
};

struct boosted_trees_stress_test  {

  void run_stress(size_t n, const std::string& run_string,
                  const std::string& target_column_str) {

    random::seed(0);

    size_t ntest = 10;

    sframe X = make_random_sframe(n, run_string, false);
    sframe X2 = make_random_sframe(ntest, run_string, false);
    sframe y = make_random_sframe(n, target_column_str, false);
    sframe y2 = make_random_sframe(ntest, target_column_str, false);
    y.set_column_name(0, "target");
    y2.set_column_name(0, "target");

    std::shared_ptr<xgboost_model> model;

    for (auto storage_mode : {storage_mode_enum::IN_MEMORY, storage_mode_enum::EXT_MEMORY}) {
      // Skip external memory stress test for large target columns
      if (storage_mode == storage_mode_enum::EXT_MEMORY &&
          (target_column_str[0] == 'S' || target_column_str[0] == 's'))
        continue;

      if(target_column_str == "n")
        model.reset(new boosted_trees_regression);
      else
        model.reset(new boosted_trees_classifier);

      // Options
      std::map<std::string, flexible_type> options = {
        {"max_iterations", 3},
      };

      model->init(X,y);
      model->init_options(options);
      model->_set_storage_mode(storage_mode);
      if (storage_mode == storage_mode_enum::EXT_MEMORY)
        model->_set_num_batches(8);
      model->train();

      // Construct the ml_data
      ml_data data = model->construct_ml_data_using_current_metadata(X2, y2);
      size_t num_classes = model->num_classes();

      // Check prediction API
      // ----------------------------------------------------------------------
      if (model->is_classifier()) {

        std::cout << "Check predict class" << std::endl;
        // predict
        auto preds = model->predict(data, "class");
        TS_ASSERT_EQUALS(preds->size(), data.num_rows());

        std::cout << "Check predict prob vector" << std::endl;

        // predict all
        auto preds_vec = model->predict(data, "probability_vector");
        TS_ASSERT_EQUALS(preds->size(), data.num_rows());

        std::cout << "Check classify " << std::endl;
        // classify
        auto classify_vec = model->classify(data);
        TS_ASSERT_EQUALS(preds->size(), data.num_rows());

        // predict topk
        std::vector<size_t> topk{1, 2, num_classes};
        for (size_t k : topk) {
          std::cout << "Check predict topk=" <<  k << std::endl;
          auto topk_preds = model->predict_topk(data, "probability", k);
          TS_ASSERT_EQUALS(topk_preds.size(), data.num_rows() * k);
          std::vector<flexible_type> probs;
          topk_preds.select_column("probability")->get_reader()->read_rows(0, topk_preds.size(), probs);
          for (auto& p : probs) {
            TS_ASSERT(p <= 1.0 && p >= 0.0);
          }
        }
      } else {
        auto preds = model->predict(data);
        TS_ASSERT_EQUALS(preds->size(), data.num_rows());
      }
    }
  }

 public:

  ////////////////////////////////////////////////////////////////////////////////
  // All the ones with targets

  void test_boosted_tree_stress000_tn() {
    // All unique
    run_stress(1, "n", "n");
  }

  void test_boosted_tree_stress0n_tn() {
    // All unique
    run_stress(5, "n", "n");
  }

  void test_boosted_tree_stress0S_tn() {
    // All unique
    run_stress(5, "s", "n");
  }

  void test_boosted_tree_stress1_unsorted_tn() {
    run_stress(5, "b", "n");
  }

  void test_boosted_tree_stress0b_tn() {
    // All unique
    run_stress(13, "S", "n");
  }

  void test_boosted_tree_stress1b_unsorted_tn() {
    run_stress(13, "b", "n");
  }

  void test_boosted_tree_stress1_tn() {
    run_stress(13, "bs", "n");
  }

  void test_boosted_tree_stress2_tn() {
    run_stress(13, "zs", "n");
  }

  void test_boosted_tree_stress3_tn() {
    run_stress(100, "Zs", "n");
  }

  void test_boosted_tree_stress4_tn() {
    // Pretty mush gonna be unique
    run_stress(100, "Ss", "n");
  }

  void test_boosted_tree_stress5_tn() {
    // 10 blocks of values.
    run_stress(1000, "Zs", "n");
  }

  void test_boosted_tree_stress6_tn() {
    // two large blocks of values
    run_stress(1000, "bs", "n");
  }

  void test_boosted_tree_stress10_tn() {
    // Yeah, a corner sase
    run_stress(1, "bc", "n");
  }

  void test_boosted_tree_stress11_tn() {
    // One with just a lot of stuff
    run_stress(200, "u", "n");
  }

  void test_boosted_tree_stress12_tn() {
    // One with just a lot of stuff
    run_stress(200, "d", "n");
  }

  void test_boosted_tree_stress13_tn() {
    // One with just a lot of stuff
    run_stress(1000, "snv", "n");
  }

  void test_boosted_tree_stress14_tn() {
    // One with just a lot of stuff
    run_stress(1000, "du", "n");
  }

  void test_boosted_tree_stress15_tn() {
    // One with just a lot of stuff
    run_stress(3, "UDssssV", "n");
  }

  void test_boosted_tree_stress15b_tn() {
    // One with just a lot of stuff
    run_stress(35, "UDssssV", "n");
  }

  void test_boosted_tree_stress15c_tn() {
    // One with just a lot of stuff
    run_stress(500, "UDsssV", "n");
  }

  void test_boosted_tree_stress100_tn() {
    // One with just a lot of stuff
    run_stress(10, "Zsuvd", "n");
  }

  void test_boosted_tree_stress16_null_tn() {
    // two large blocks of values
    run_stress(1000, "S", "n");
  }

  void test_boosted_tree_stress000_tc() {
    // All unique
    run_stress(2, "n", "s");
  }

  void test_boosted_tree_stress0n_tc() {
    // All unique
    run_stress(5, "n", "s");
  }

  void test_boosted_tree_stress0S_tc() {
    // All unique
    run_stress(5, "s", "s");
  }

  void test_boosted_tree_stress1_unsorted_tc() {
    run_stress(5, "b", "s");
  }

  void test_boosted_tree_stress0b_tc() {
    // All unique
    run_stress(13, "S", "s");
  }

  void test_boosted_tree_stress1b_unsorted_tc() {
    run_stress(13, "b", "s");
  }

  void test_boosted_tree_stress1_tc() {
    run_stress(13, "bs", "s");
  }

  void test_boosted_tree_stress2_tc() {
    run_stress(13, "zs", "s");
  }

  void test_boosted_tree_stress3_tc() {
    run_stress(100, "Zs", "s");
  }

  void test_boosted_tree_stress4_tc() {
    // Pretty mush gonna be unique
    run_stress(100, "Ss", "s");
  }

  void test_boosted_tree_stress5_tc() {
    // 10 blocks of values.
    run_stress(1000, "Zs", "s");
  }

  void test_boosted_tree_stress6_tc() {
    // two large blocks of values
    run_stress(1000, "bs", "s");
  }

  void test_boosted_tree_stress10_tc() {
    // Yeah, a corner sase
    run_stress(2, "bc", "s");
  }

  void test_boosted_tree_stress11_tc() {
    // One with just a lot of stuff
    run_stress(200, "u", "s");
  }

  void test_boosted_tree_stress12_tc() {
    // One with just a lot of stuff
    run_stress(200, "d", "s");
  }

  void test_boosted_tree_stress13_tc() {
    // One with just a lot of stuff
    run_stress(1000, "snv", "s");
  }

  void test_boosted_tree_stress14_tc() {
    // One with just a lot of stuff
    run_stress(1000, "du", "s");
  }

  void test_boosted_tree_stress15_tc() {
    // One with just a lot of stuff
    run_stress(3, "UDssssV", "s");
  }

  void test_boosted_tree_stress15b_tc() {
    // One with just a lot of stuff
    run_stress(35, "UDssssV", "s");
  }

  void test_boosted_tree_stress15c_tc() {
    // One with just a lot of stuff
    run_stress(500, "UDsssV", "s");
  }

  void test_boosted_tree_stress100_tc() {
    // One with just a lot of stuff
    run_stress(10, "Zsuvd", "s");
  }

  void test_boosted_tree_stress16_null_tc() {
    // two large blocks of values
    run_stress(1000, "S", "s");
  }

  //////////////////////////////////////////////////////////////////////////////

  void test_boosted_tree_stress000_tC() {
    // All unique
    run_stress(2, "n", "S");
  }

  void test_boosted_tree_stress0n_tC() {
    // All unique
    run_stress(5, "n", "S");
  }

  void test_boosted_tree_stress0S_tC() {
    // All unique
    run_stress(5, "s", "S");
  }

  void test_boosted_tree_stress1_unsorted_tC() {
    run_stress(5, "b", "S");
  }

  void test_boosted_tree_stress0b_tC() {
    // All unique
    run_stress(13, "S", "S");
  }

  void test_boosted_tree_stress1b_unsorted_tC() {
    run_stress(13, "b", "S");
  }

  void test_boosted_tree_stress1_tC() {
    run_stress(13, "bs", "S");
  }

  void test_boosted_tree_stress2_tC() {
    run_stress(13, "zs", "S");
  }

  void test_boosted_tree_stress3_tC() {
    run_stress(100, "Zs", "S");
  }

  void test_boosted_tree_stress4_tC() {
    // Pretty mush gonna be unique
    run_stress(100, "Ss", "S");
  }

  void test_boosted_tree_stress5_tC() {
    // 10 blocks of values.
    run_stress(1000, "Zs", "S");
  }

  void test_boosted_tree_stress6_tC() {
    // two large blocks of values
    run_stress(1000, "bs", "S");
  }

  void test_boosted_tree_stress10_tC() {
    // Yeah, a corner sase
    run_stress(2, "bc", "S");
  }

  void test_boosted_tree_stress11_tC() {
    // One with just a lot of stuff
    run_stress(200, "u", "S");
  }

  void test_boosted_tree_stress12_tC() {
    // One with just a lot of stuff
    run_stress(200, "d", "S");
  }

  void test_boosted_tree_stress13_tC() {
    // One with just a lot of stuff
    run_stress(1000, "snv", "S");
  }

  void test_boosted_tree_stress14_tC() {
    // One with just a lot of stuff
    run_stress(1000, "du", "S");
  }

  void test_boosted_tree_stress15_tC() {
    // One with just a lot of stuff
    run_stress(3, "UDssssV", "S");
  }

  void test_boosted_tree_stress15b_tC() {
    // One with just a lot of stuff
    run_stress(35, "UDssssV", "S");
  }

  void test_boosted_tree_stress15c_tC() {
    // One with just a lot of stuff
    run_stress(500, "UDsssV", "S");
  }

  void test_boosted_tree_stress100_tC() {
    // One with just a lot of stuff
    run_stress(10, "Zsuvd", "S");
  }

  void test_boosted_tree_stress16_null_tC() {
    // two large blocks of values
    run_stress(1000, "S", "S");
  }

};

BOOST_FIXTURE_TEST_SUITE(_boosted_trees_classifier_test, boosted_trees_classifier_test)
BOOST_AUTO_TEST_CASE(test_boosted_trees_classifier_basic_2d) {
  boosted_trees_classifier_test::test_boosted_trees_classifier_basic_2d();
}
BOOST_AUTO_TEST_CASE(test_boosted_trees_classifier_small) {
  boosted_trees_classifier_test::test_boosted_trees_classifier_small();
}
BOOST_AUTO_TEST_CASE(test_boosted_trees_classifier_with_insufficient_column_subsample) {
  boosted_trees_classifier_test::test_boosted_trees_classifier_with_insufficient_column_subsample();
}
BOOST_AUTO_TEST_CASE(test_boosted_trees_classifier_external_memory) {
  boosted_trees_classifier_test::test_boosted_trees_classifier_external_memory();
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_FIXTURE_TEST_SUITE(_boosted_trees_stress_test, boosted_trees_stress_test)
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress000_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress000_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0n_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress0n_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0S_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress0S_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_unsorted_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress1_unsorted_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0b_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress0b_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1b_unsorted_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress1b_unsorted_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress1_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress2_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress2_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress3_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress3_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress4_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress4_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress5_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress5_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress6_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress6_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress10_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress10_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress11_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress11_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress12_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress12_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress13_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress13_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress14_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress14_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress15_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15b_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress15b_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15c_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress15c_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress100_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress100_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress16_null_tn) {
  boosted_trees_stress_test::test_boosted_tree_stress16_null_tn();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress000_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress000_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0n_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress0n_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0S_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress0S_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_unsorted_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress1_unsorted_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0b_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress0b_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1b_unsorted_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress1b_unsorted_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress1_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress2_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress2_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress3_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress3_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress4_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress4_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress5_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress5_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress6_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress6_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress10_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress10_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress11_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress11_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress12_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress12_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress13_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress13_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress14_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress14_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress15_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15b_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress15b_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15c_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress15c_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress100_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress100_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress16_null_tc) {
  boosted_trees_stress_test::test_boosted_tree_stress16_null_tc();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress000_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress000_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0n_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress0n_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0S_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress0S_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_unsorted_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress1_unsorted_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress0b_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress0b_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1b_unsorted_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress1b_unsorted_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress1_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress1_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress2_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress2_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress3_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress3_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress4_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress4_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress5_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress5_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress6_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress6_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress10_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress10_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress11_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress11_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress12_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress12_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress13_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress13_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress14_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress14_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress15_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15b_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress15b_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress15c_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress15c_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress100_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress100_tC();
}
BOOST_AUTO_TEST_CASE(test_boosted_tree_stress16_null_tC) {
  boosted_trees_stress_test::test_boosted_tree_stress16_null_tC();
}
BOOST_AUTO_TEST_SUITE_END()

ext: cxx

max_stars_repo_name: LeeCenY/turicreate

max_issues_repo_name: LeeCenY/turicreate

max_forks_repo_name: ZeroInfinite/turicreate