<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

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

//==============================================================================
// User message widget
//==============================================================================

#include "guiutils.h"
#include "usermessagewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QBuffer>
#include <QFont>
#include <QIcon>
#include <QSizePolicy>
#include <QWidget>

//==============================================================================

namespace OpenCOR {
namespace Core {

//==============================================================================

void UserMessageWidget::constructor(const QString &pIcon,
                                    const QString &pMessage,
                                    const QString &pExtraMessage)
{
    // Some initialisations

    mIcon = QString();
    mMessage = QString();
    mExtraMessage = QString();

    // Customise our background

    setAutoFillBackground(true);
    setBackgroundRole(QPalette::Base);

    // Increase the size of our font

    QFont newFont = font();

    newFont.setPointSizeF(1.35*newFont.pointSize());

    setFont(newFont);

    // Some other customisations

    setContextMenuPolicy(Qt::NoContextMenu);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setWordWrap(true);

    // 'Initialise' our message

    setIconMessage(pIcon, pMessage, pExtraMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon,
                                     const QString &pMessage,
                                     const QString &pExtraMessage,
                                     QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon, pMessage, pExtraMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon,
                                     const QString &pMessage,
                                     QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon, pMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon, QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor();
}

//==============================================================================

void UserMessageWidget::setIconMessage(const QString &pIcon,
                                       const QString &pMessage,
                                       const QString &pExtraMessage)
{
    // Set our message, if needed

    if (   pIcon.compare(mIcon)
        || pMessage.compare(mMessage)
        || pExtraMessage.compare(mExtraMessage)) {
        // Keep track of the new values for our icon, message and extra message

        mIcon = pIcon;
        mMessage = pMessage;
        mExtraMessage = pExtraMessage;

        // Set our text as HTML
        // Note: we want our icon to have a final size of 32px by 32px. However,
        //       it may be that it has a different size to begin with. Normally,
        //       we would rely on QLabel's HTML support (and in particular on
        //       the width and height attributes of the img element) to have our
        //       icon resized for us, but this results in a pixelated and
        //       therefore ugly image. So, instead, we retrieve a data URI for
        //       our resized icon...

        if (mExtraMessage.isEmpty())
            setText(QString("
"
                            "
"
                            "
"
                            "            "
                            "                "
                            "            	"
                            "            "
                            "
"
                            "                    %2"
                            "
"
                            "            	"
                            "
"
                            "
"
                            "
").arg(iconDataUri(mIcon, 32, 32), mMessage));
        else
            setText(QString("
"
                            "
"
                            "
"
                            "            "
                            "                "
                            "            	"
                            "            "
                            "
"
                            "                    %2"
                            "
"
                            "
"
                            "                    (%3)"
                            "
"
                            "            	"
                            "
"
                            "
"
                            "
").arg(iconDataUri(mIcon, 32, 32), mMessage, mExtraMessage));
    }
}

//==============================================================================

void UserMessageWidget::setMessage(const QString &pMessage,
                                   const QString &pExtraMessage)
{
    // Set our message

    setIconMessage(mIcon, pMessage, pExtraMessage);
}

//==============================================================================

}   // namespace Core
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

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

//==============================================================================
// User message widget
//==============================================================================

#include "guiutils.h"
#include "usermessagewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QBuffer>
#include <QFont>
#include <QIcon>
#include <QSizePolicy>
#include <QWidget>

//==============================================================================

namespace OpenCOR {
namespace Core {

//==============================================================================

void UserMessageWidget::constructor(const QString &pIcon,
                                    const QString &pMessage,
                                    const QString &pExtraMessage)
{
    // Some initialisations

    mIcon = QString();
    mMessage = QString();
    mExtraMessage = QString();

    // Customise our background

    setAutoFillBackground(true);
    setBackgroundRole(QPalette::Base);

    // Increase the size of our font

    QFont newFont = font();

    newFont.setPointSizeF(1.35*newFont.pointSize());

    setFont(newFont);

    // Some other customisations

    setContextMenuPolicy(Qt::NoContextMenu);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setWordWrap(true);

    // 'Initialise' our message

    setIconMessage(pIcon, pMessage, pExtraMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon,
                                     const QString &pMessage,
                                     const QString &pExtraMessage,
                                     QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon, pMessage, pExtraMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon,
                                     const QString &pMessage,
                                     QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon, pMessage);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(const QString &pIcon, QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor(pIcon);
}

//==============================================================================

UserMessageWidget::UserMessageWidget(QWidget *pParent) :
    QLabel(pParent)
{
    // Construct our object

    constructor();
}

//==============================================================================

void UserMessageWidget::setIconMessage(const QString &pIcon,
                                       const QString &pMessage,
                                       const QString &pExtraMessage)
{
    // Set our message, if needed

    if (   pIcon.compare(mIcon)
        || pMessage.compare(mMessage)
        || pExtraMessage.compare(mExtraMessage)) {
        // Keep track of the new values for our icon, message and extra message

        mIcon = pIcon;
        mMessage = pMessage;
        mExtraMessage = pExtraMessage;

        // Set our text as HTML
        // Note: we want our icon to have a final size of 32px by 32px. However,
        //       it may be that it has a different size to begin with. Normally,
        //       we would rely on QLabel's HTML support (and in particular on
        //       the width and height attributes of the img element) to have our
        //       icon resized for us, but this results in a pixelated and
        //       therefore ugly image. So, instead, we retrieve a data URI for
        //       our resized icon...

        if (mExtraMessage.isEmpty())
            setText(QString("
\n"
                            "
\n"
                            "
\n"
                            "            \n"
                            "                \n"
                            "            	\n"
                            "            \n"
                            "
\n"
                            "                    %2\n"
                            "
\n"
                            "            	\n"
                            "
\n"
                            "
\n"
                            "
\n").arg(iconDataUri(mIcon, 32, 32), mMessage));
        else
            setText(QString("
\n"
                            "
\n"
                            "
\n"
                            "            \n"
                            "                \n"
                            "            	\n"
                            "            \n"
                            "
\n"
                            "                    %2\n"
                            "
\n"
                            "
\n"
                            "                    (%3)\n"
                            "
\n"
                            "            	\n"
                            "
\n"
                            "
\n"
                            "
\n").arg(iconDataUri(mIcon, 32, 32), mMessage, mExtraMessage));
    }
}

//==============================================================================

void UserMessageWidget::setMessage(const QString &pMessage,
                                   const QString &pExtraMessage)
{
    // Set our message

    setIconMessage(mIcon, pMessage, pExtraMessage);
}

//==============================================================================

}   // namespace Core
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/*
 *     Copyright 2010-2012 Couchbase, 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 "internal.h"
#include "simplestring.h"
#include <http/http.h>

static void
flush_cb(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
{
    const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)rb;
    lcb_RESPCBFLUSH fresp = { 0 };
    lcb_RESPCALLBACK callback = lcb_find_callback(instance, LCB_CALLBACK_CBFLUSH);

    fresp = *(lcb_RESPBASE *)rb;
    fresp.rflags |= LCB_RESP_F_FINAL;
    if (resp->rc == LCB_SUCCESS) {
        if (resp->htstatus < 200 || resp->htstatus > 299) {
            fresp.rc = LCB_HTTP_ERROR;
        }
    }
    if (callback) {
        callback(instance, LCB_CALLBACK_CBFLUSH, (lcb_RESPBASE*)&fresp);
    }
    (void)cbtype;
}

LIBCOUCHBASE_API
lcb_error_t
lcb_cbflush3(lcb_t instance, const void *cookie, const lcb_CMDBASE *cmd)
{
    lcb_http_request_t htr;
    lcb_CMDHTTP htcmd = { 0 };
    lcb_string urlpath;
    lcb_error_t rc;

    (void)cmd;

    lcb_string_init(&urlpath);
    lcb_string_appendz(&urlpath, "/pools/default/buckets/");
    lcb_string_appendz(&urlpath, LCBT_SETTING(instance, bucket));
    lcb_string_appendz(&urlpath, "/controller/doFlush");

    htcmd.type = LCB_HTTP_TYPE_MANAGEMENT;
    htcmd.method = LCB_HTTP_METHOD_POST;
    htcmd.reqhandle = &htr;
    LCB_CMD_SET_KEY(&htcmd, urlpath.base, urlpath.nused);

    rc = lcb_http3(instance, cookie, &htcmd);
    lcb_string_release(&urlpath);

    if (rc != LCB_SUCCESS) {
        return rc;
    }
    lcb_htreq_setcb(htr, flush_cb);
    return LCB_SUCCESS;
}
<commit_msg>cbflush: Use std::string<commit_after>/*
 *     Copyright 2010-2012 Couchbase, 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 "internal.h"
#include <http/http.h>

static void
flush_cb(lcb_t instance, int, const lcb_RESPBASE *rb)
{
    const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)rb;
    lcb_RESPCBFLUSH fresp = { 0 };
    lcb_RESPCALLBACK callback = lcb_find_callback(instance, LCB_CALLBACK_CBFLUSH);

    fresp = *(lcb_RESPBASE *)rb;
    fresp.rflags |= LCB_RESP_F_FINAL;
    if (resp->rc == LCB_SUCCESS) {
        if (resp->htstatus < 200 || resp->htstatus > 299) {
            fresp.rc = LCB_HTTP_ERROR;
        }
    }
    if (callback) {
        callback(instance, LCB_CALLBACK_CBFLUSH, (lcb_RESPBASE*)&fresp);
    }
}

LIBCOUCHBASE_API
lcb_error_t
lcb_cbflush3(lcb_t instance, const void *cookie, const lcb_CMDBASE *)
{
    lcb_http_request_t htr;
    lcb_CMDHTTP htcmd = { 0 };
    lcb_error_t rc;

    std::string urlpath("/pools/default/buckets/");
    urlpath.append(LCBT_SETTING(instance, bucket));
    urlpath.append("/controller/doFlush");

    htcmd.type = LCB_HTTP_TYPE_MANAGEMENT;
    htcmd.method = LCB_HTTP_METHOD_POST;
    htcmd.reqhandle = &htr;
    LCB_CMD_SET_KEY(&htcmd, urlpath.c_str(), urlpath.size());

    rc = lcb_http3(instance, cookie, &htcmd);

    if (rc != LCB_SUCCESS) {
        return rc;
    }
    lcb_htreq_setcb(htr, flush_cb);
    return LCB_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "operators/operator.h"

#include <cstring>

#include <string>

#include "modsecurity/assay.h"

#include "operators/detect_sqli.h"
#include "operators/detect_xss.h"
#include "operators/inspect_file.h"
#include "operators/fuzzy_hash.h"
#include "operators/validate_byte_range.h"
#include "operators/validate_dtd.h"
#include "operators/validate_hash.h"
#include "operators/validate_schema.h"
#include "operators/validate_url_encoding.h"
#include "operators/validate_utf8_encoding.h"
#include "operators/verify_cc.h"
#include "operators/verify_cpf.h"
#include "operators/verify_ssn.h"
#include "operators/geo_lookup.h"
#include "operators/gsblookup.h"
#include "operators/rsub.h"
#include "operators/within.h"
#include "operators/contains_word.h"
#include "operators/contains.h"
#include "operators/ends_with.h"
#include "operators/eq.h"
#include "operators/ge.h"
#include "operators/gt.h"
#include "operators/ip_match_f.h"
#include "operators/ip_match.h"
#include "operators/ip_match_from_file.h"
#include "operators/le.h"
#include "operators/lt.h"
#include "operators/pm_f.h"
#include "operators/pm.h"
#include "operators/pm_from_file.h"
#include "operators/rbl.h"
#include "operators/rx.h"
#include "operators/str_eq.h"
#include "operators/str_match.h"
#include "operators/begins_with.h"

#define IF_MATCH(a) \
    if (op_ == #a)

namespace ModSecurity {
namespace operators {

bool Operator::debug(Assay *assay, int x, std::string a) {
    assay->debug(x, a);
    return true;
}

bool Operator::evaluate(Assay *assay) {
    if (assay) {
        assay->debug(2, "Operator: " + this->op + \
            " is not implemented or malfunctioning.");
    } else {
        std::cerr << "Operator: " + this->op + \
            " is not implemented or malfunctioning.";
    }
    return true;
}

bool Operator::evaluate(Assay *assay, const std::string& a) {
    if (assay) {
        assay->debug(2, "Operator: " + this->op + \
            " is not implemented or malfunctioning.");
    } else {
        std::cerr << "Operator: " + this->op + \
            " is not implemented or malfunctioning.";
    }

    return true;
}

Operator *Operator::instantiate(std::string op_string) {
    // Sanity check.
    if (op_string.size() <= 2) {
        return NULL;
    }

    std::string op = op_string;
    op = op.substr(1, op_string.size() - 2);

    // We assume no negation by default
    bool negation = false;
    // If there is a '!' in front substring and assign negation
    if (op.at(0) == '!') {
       op = op.substr(1, op.size() - 1);
       negation = true;
    }

    // Check to see if there is a parameter, if not param is an empty string
    std::string param = "";
    if (op.find(" ") != std::string::npos) {
        param = op;
        param.erase(0, op_string.find(" "));
        op.erase(op_string.find(" "),
            op_string.length() - op_string.find(" "));
    }

    for (std::basic_string<char>::iterator p = op.begin();
        p != op.end(); ++p) {
       *p = tolower(*p);
    }
    std::string op_ = op;
    if (op_.length() > 2) {
        op_.erase(0, 1);
        op_.pop_back();
    }

    IF_MATCH(beginswith) { return new BeginsWith(op, param, negation); }
    IF_MATCH(contains) { return new Contains(op, param, negation); }
    IF_MATCH(containsword) { return new ContainsWord(op, param, negation); }
    IF_MATCH(detectsqli) { return new DetectSQLi(op, param, negation); }
    IF_MATCH(detectxss) { return new DetectXSS(op, param, negation); }
    IF_MATCH(endswith) { return new EndsWith(op, param, negation); }
    IF_MATCH(eq) { return new Eq(op, param, negation); }
    IF_MATCH(fuzzyhash) { return new FuzzyHash(op, param, negation); }
    IF_MATCH(geolooku) { return new GeoLookup(op, param, negation); }
    IF_MATCH(ge) { return new Ge(op, param, negation); }
    IF_MATCH(gsblookup) { return new GsbLookup(op, param, negation); }
    IF_MATCH(gt) { return new Gt(op, param, negation); }
    IF_MATCH(inspectfile) { return new InspectFile(op, param, negation); }
    IF_MATCH(ipmatchf) { return new IpMatchF(op, param, negation); }
    IF_MATCH(ipmatchfromfile) {
        return new IpMatchFromFile(op, param, negation);
    }
    IF_MATCH(ipmatch) { return new IpMatch(op, param, negation); }
    IF_MATCH(le) { return new Le(op, param, negation); }
    IF_MATCH(lt) { return new Lt(op, param, negation); }
    IF_MATCH(pmf) { return new PmF(op, param, negation); }
    IF_MATCH(pmfromfile) { return new PmFromFile(op, param, negation); }
    IF_MATCH(pm) { return new Pm(op, param, negation); }
    IF_MATCH(rbl) { return new Rbl(op, param, negation); }
    IF_MATCH(rsub) { return new Rsub(op, param, negation); }
    IF_MATCH(rx) { return new Rx(op, param, negation); }
    IF_MATCH(streq) { return new StrEq(op, param, negation); }
    IF_MATCH(strmatch) { return new StrMatch(op, param, negation); }
    IF_MATCH(validatebyterange) {
        return new ValidateByteRange(op, param, negation);
    }
    IF_MATCH(validatedtd) { return new ValidateDTD(op, param, negation); }
    IF_MATCH(validatehash) { return new ValidateHash(op, param, negation); }
    IF_MATCH(validateschema) { return new ValidateSchema(op, param, negation); }
    IF_MATCH(validateurlencoding) {
        return new ValidateUrlEncoding(op, param, negation);
    }
    IF_MATCH(validateutf8encoding) {
        return new ValidateUtf8Encoding(op, param, negation);
    }
    IF_MATCH(verifycc) { return new VerifyCC(op, param, negation); }
    IF_MATCH(verifycpf) { return new VerifyCPF(op, param, negation); }
    IF_MATCH(verifyssn) { return new VerifySSN(op, param, negation); }
    IF_MATCH(within) { return new Within(op, param, negation); }

    return new Operator(op, param, negation);
}

}  // namespace operators
}  // namespace ModSecurity

<commit_msg>Fix operator instantiation/selection<commit_after>/*
 * ModSecurity, http://www.modsecurity.org/
 * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
 *
 * 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
 *
 * If any of the files related to licensing are missing or if you have any
 * other questions related to licensing please contact Trustwave Holdings, Inc.
 * directly using the email address security@modsecurity.org.
 *
 */

#include "operators/operator.h"

#include <cstring>

#include <string>

#include "modsecurity/assay.h"

#include "operators/detect_sqli.h"
#include "operators/detect_xss.h"
#include "operators/inspect_file.h"
#include "operators/fuzzy_hash.h"
#include "operators/validate_byte_range.h"
#include "operators/validate_dtd.h"
#include "operators/validate_hash.h"
#include "operators/validate_schema.h"
#include "operators/validate_url_encoding.h"
#include "operators/validate_utf8_encoding.h"
#include "operators/verify_cc.h"
#include "operators/verify_cpf.h"
#include "operators/verify_ssn.h"
#include "operators/geo_lookup.h"
#include "operators/gsblookup.h"
#include "operators/rsub.h"
#include "operators/within.h"
#include "operators/contains_word.h"
#include "operators/contains.h"
#include "operators/ends_with.h"
#include "operators/eq.h"
#include "operators/ge.h"
#include "operators/gt.h"
#include "operators/ip_match_f.h"
#include "operators/ip_match.h"
#include "operators/ip_match_from_file.h"
#include "operators/le.h"
#include "operators/lt.h"
#include "operators/pm_f.h"
#include "operators/pm.h"
#include "operators/pm_from_file.h"
#include "operators/rbl.h"
#include "operators/rx.h"
#include "operators/str_eq.h"
#include "operators/str_match.h"
#include "operators/begins_with.h"

#define IF_MATCH(a) \
    if (op_ == #a)

namespace ModSecurity {
namespace operators {

bool Operator::debug(Assay *assay, int x, std::string a) {
    assay->debug(x, a);
    return true;
}

bool Operator::evaluate(Assay *assay) {
    if (assay) {
        assay->debug(2, "Operator: " + this->op + \
            " is not implemented or malfunctioning.");
    } else {
        std::cerr << "Operator: " + this->op + \
            " is not implemented or malfunctioning.";
    }
    return true;
}

bool Operator::evaluate(Assay *assay, const std::string& a) {
    if (assay) {
        assay->debug(2, "Operator: " + this->op + \
            " is not implemented or malfunctioning.");
    } else {
        std::cerr << "Operator: " + this->op + \
            " is not implemented or malfunctioning.";
    }

    return true;
}

Operator *Operator::instantiate(std::string op_string) {
    // Sanity check.
    if (op_string.size() <= 2) {
        return NULL;
    }

    std::string op = op_string;
    op = op.substr(1, op_string.size() - 2);

    // We assume no negation by default
    bool negation = false;
    // If there is a '!' in front substring and assign negation
    if (op.at(0) == '!') {
       op = op.substr(1, op.size() - 1);
       negation = true;
    }

    // Check to see if there is a parameter, if not param is an empty string
    std::string param = "";
    if (op.find(" ") != std::string::npos) {
        param = op;
        param.erase(0, op_string.find(" "));
        op.erase(op_string.find(" "),
            op_string.length() - op_string.find(" "));
    }

    for (std::basic_string<char>::iterator p = op.begin();
        p != op.end(); ++p) {
       *p = tolower(*p);
    }
    std::string op_ = op;
    if (op_.length() > 2) {
        op_.erase(0, 1);
        if (op_.back() == ' ') {
            op_.pop_back();
        }
    }

    IF_MATCH(beginswith) { return new BeginsWith(op, param, negation); }
    IF_MATCH(contains) { return new Contains(op, param, negation); }
    IF_MATCH(containsword) { return new ContainsWord(op, param, negation); }
    IF_MATCH(detectsqli) { return new DetectSQLi(op, param, negation); }
    IF_MATCH(detectxss) { return new DetectXSS(op, param, negation); }
    IF_MATCH(endswith) { return new EndsWith(op, param, negation); }
    IF_MATCH(eq) { return new Eq(op, param, negation); }
    IF_MATCH(fuzzyhash) { return new FuzzyHash(op, param, negation); }
    IF_MATCH(geolookup) { return new GeoLookup(op, param, negation); }
    IF_MATCH(ge) { return new Ge(op, param, negation); }
    IF_MATCH(gsblookup) { return new GsbLookup(op, param, negation); }
    IF_MATCH(gt) { return new Gt(op, param, negation); }
    IF_MATCH(inspectfile) { return new InspectFile(op, param, negation); }
    IF_MATCH(ipmatchf) { return new IpMatchF(op, param, negation); }
    IF_MATCH(ipmatchfromfile) {
        return new IpMatchFromFile(op, param, negation);
    }
    IF_MATCH(ipmatch) { return new IpMatch(op, param, negation); }
    IF_MATCH(le) { return new Le(op, param, negation); }
    IF_MATCH(lt) { return new Lt(op, param, negation); }
    IF_MATCH(pmf) { return new PmF(op, param, negation); }
    IF_MATCH(pmfromfile) { return new PmFromFile(op, param, negation); }
    IF_MATCH(pm) { return new Pm(op, param, negation); }
    IF_MATCH(rbl) { return new Rbl(op, param, negation); }
    IF_MATCH(rsub) { return new Rsub(op, param, negation); }
    IF_MATCH(rx) { return new Rx(op, param, negation); }
    IF_MATCH(streq) { return new StrEq(op, param, negation); }
    IF_MATCH(strmatch) { return new StrMatch(op, param, negation); }
    IF_MATCH(validatebyterange) {
        return new ValidateByteRange(op, param, negation);
    }
    IF_MATCH(validatedtd) { return new ValidateDTD(op, param, negation); }
    IF_MATCH(validatehash) { return new ValidateHash(op, param, negation); }
    IF_MATCH(validateschema) { return new ValidateSchema(op, param, negation); }
    IF_MATCH(validateurlencoding) {
        return new ValidateUrlEncoding(op, param, negation);
    }
    IF_MATCH(validateutf8encoding) {
        return new ValidateUtf8Encoding(op, param, negation);
    }
    IF_MATCH(verifycc) { return new VerifyCC(op, param, negation); }
    IF_MATCH(verifycpf) { return new VerifyCPF(op, param, negation); }
    IF_MATCH(verifyssn) { return new VerifySSN(op, param, negation); }
    IF_MATCH(within) { return new Within(op, param, negation); }

    return new Operator(op, param, negation);
}

}  // namespace operators
}  // namespace ModSecurity

<|endoftext|>


<commit_before>#include <type_traits>

namespace Lambda {
	using namespace std;

	struct Functor {};

	template<typename _Type>
	struct IsBound {
		static bool constexpr s_f = !is_base_of<
			Functor,
			typename remove_cv<
				typename remove_reference<_Type>::type
				>::type
			>::value;
	};

	template<typename _Type, bool _fBound = IsBound<_Type>::s_f>
	struct FunctorTraits;

	template<typename _Type>
	struct FunctorTraits<_Type, true> {};

	template<typename _Type>
	inline _Type &&Pass(_Type &&rr) {
		return rr;
	}

	template<unsigned int _i>
	struct Bind :
		public Functor
	{
		template<typename _First, typename... _Other>
		inline static auto Apply(_First&&, _Other&&... rrOther) -> decltype(Bind<_i - 1>::Apply(rrOther...)) {
			return Bind<_i - 1>::Apply(rrOther...);
		}

		template<typename... _Arguments>
		inline auto operator () (_Arguments&&... rrArguments) -> decltype(Bind<_i>::Apply(rrArguments...)) {
			return Bind<_i>::Apply(rrArguments...);
		}
	};

	template<>
	struct Bind<0> :
		public Functor
	{
		template<typename _Type, typename... _Other>
		inline static _Type &&Apply(_Type &&rr, _Other&&...) {
			return rr;
		}

		template<typename _Type, typename... _Other>
		inline _Type &&operator () (_Type &&rr, _Other&&...) {
			return rr;
		}
	};

#define LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Operand, bool _fBound = IsBound<_Operand>::s_f> \
	struct Name; \
	template<typename _Operand> \
	struct Name<_Operand, false> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(Operator(m_Operand(Arguments...))) { \
			return Operator(m_Operand(Arguments...)); \
		} \
	}; \
	template<typename _Operand> \
	struct Name<_Operand, true> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(Operator m_Operand) { \
			return Operator m_Operand; \
		} \
	};

#define LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Operand, bool _fBound = IsBound<_Operand>::s_f> \
	struct Name; \
	template<typename _Operand> \
	struct Name<_Operand, false> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype((m_Operand(Arguments...)) Operator) { \
			return (m_Operand(Arguments...)) Operator; \
		} \
	}; \
	template<typename _Operand> \
	struct Name<_Operand, true> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(m_Operand Operator) { \
			return m_Operand Operator; \
		} \
	};

LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(+, UnaryPlus)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(-, UnaryMinus)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(!, LogicalNot)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(~, BitwiseNot)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(++, PreIncrement)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(--, PreDecrement)
LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(++, PostIncrement)
LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(--, PostDecrement)

#define LAMBDA_BINARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Left, typename _Right, bool _fLeftBound = IsBound<_Left>::s_f, bool _fRightBound = IsBound<_Right>::s_f> \
	struct Name; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, false, false> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left(Arguments...) Operator m_Right(Arguments...)) { \
			return m_Left(Arguments...) Operator m_Right(Arguments...); \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, true, false> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left Operator m_Right(Arguments...)) { \
			return m_Left Operator m_Right(Arguments...); \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, false, true> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left(Arguments...) Operator m_Right) { \
			return m_Left(Arguments...) Operator m_Right; \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, true, true> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(m_Left Operator m_Right) { \
			return m_Left Operator m_Right; \
		} \
	};

LAMBDA_BINARY_FUNCTOR_CLASS(+, BinaryPlus)
LAMBDA_BINARY_FUNCTOR_CLASS(+=, CompoundPlus)
LAMBDA_BINARY_FUNCTOR_CLASS(-, BinaryMinus)
LAMBDA_BINARY_FUNCTOR_CLASS(-=, CompoundMinus)
LAMBDA_BINARY_FUNCTOR_CLASS(*, Multiply)
LAMBDA_BINARY_FUNCTOR_CLASS(*=, CompoundMultiply)
LAMBDA_BINARY_FUNCTOR_CLASS(/, Divide)
LAMBDA_BINARY_FUNCTOR_CLASS(/=, CompoundDivide)
LAMBDA_BINARY_FUNCTOR_CLASS(%, Modulus)
LAMBDA_BINARY_FUNCTOR_CLASS(%=, CompoundModulus)
LAMBDA_BINARY_FUNCTOR_CLASS(&, BitwiseAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(|, BitwiseOr)
LAMBDA_BINARY_FUNCTOR_CLASS(^, BitwiseXor)
LAMBDA_BINARY_FUNCTOR_CLASS(&=, CompoundAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(|=, CompoundOr)
LAMBDA_BINARY_FUNCTOR_CLASS(^=, CompoundXor)
LAMBDA_BINARY_FUNCTOR_CLASS(&&, LogicalAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(||, LogicalOr)
LAMBDA_BINARY_FUNCTOR_CLASS(<<, LeftShift)
LAMBDA_BINARY_FUNCTOR_CLASS(<<=, CompoundLeftShift)
LAMBDA_BINARY_FUNCTOR_CLASS(>>, RightShift)
LAMBDA_BINARY_FUNCTOR_CLASS(>>=, CompoundRightShift)
LAMBDA_BINARY_FUNCTOR_CLASS(=, Assignment)
LAMBDA_BINARY_FUNCTOR_CLASS(==, Equals)
LAMBDA_BINARY_FUNCTOR_CLASS(!=, NotEqual)
LAMBDA_BINARY_FUNCTOR_CLASS(<, LessThan)
LAMBDA_BINARY_FUNCTOR_CLASS(>, GreaterThan)
LAMBDA_BINARY_FUNCTOR_CLASS(<=, LessThanOrEqualTo)
LAMBDA_BINARY_FUNCTOR_CLASS(>=, GreaterThanOrEqualTo)

}

Lambda::Bind<0> _1;
Lambda::Bind<1> _2;
Lambda::Bind<2> _3;
Lambda::Bind<3> _4;
Lambda::Bind<4> _5;
Lambda::Bind<5> _6;
Lambda::Bind<6> _7;
Lambda::Bind<7> _8;
Lambda::Bind<8> _9;
Lambda::Bind<9> _10;

#define LAMBDA_PREFIX_UNARY_OPERATOR(Operator, FunctorClass) \
	template<typename _Operand, typename _Traits = Lambda::FunctorTraits<_Operand>> \
	inline Lambda::FunctorClass<_Operand> operator Operator (_Operand &&rrOperand) { \
		return Lambda::FunctorClass<_Operand>((_Operand&&)rrOperand); \
	}

LAMBDA_PREFIX_UNARY_OPERATOR(+, UnaryPlus)
LAMBDA_PREFIX_UNARY_OPERATOR(-, UnaryMinus)
LAMBDA_PREFIX_UNARY_OPERATOR(!, LogicalNot)
LAMBDA_PREFIX_UNARY_OPERATOR(~, BitwiseNot)
LAMBDA_PREFIX_UNARY_OPERATOR(++, PreIncrement)
LAMBDA_PREFIX_UNARY_OPERATOR(--, PreDecrement)

#define LAMBDA_BINARY_OPERATOR(Operator, FunctorClass) \
	template<typename _Left, typename _Right, typename _LeftTraits = Lambda::FunctorTraits<_Left>, typename _RightTraits = Lambda::FunctorTraits<_Right>> \
	inline Lambda::FunctorClass<_Left, _Right> operator Operator (_Left &&rrLeft, _Right &&rrRight) { \
		return Lambda::FunctorClass<_Left, _Right>((_Left&&)rrLeft, (_Right&&)rrRight); \
	}

LAMBDA_BINARY_OPERATOR(+, BinaryPlus)
LAMBDA_BINARY_OPERATOR(+=, CompoundPlus)
LAMBDA_BINARY_OPERATOR(-, BinaryMinus)
LAMBDA_BINARY_OPERATOR(-=, CompoundMinus)
LAMBDA_BINARY_OPERATOR(*, Multiply)
LAMBDA_BINARY_OPERATOR(*=, CompoundMultiply)
LAMBDA_BINARY_OPERATOR(/, Divide)
LAMBDA_BINARY_OPERATOR(/=, CompoundDivide)
LAMBDA_BINARY_OPERATOR(%, Modulus)
LAMBDA_BINARY_OPERATOR(%=, CompoundModulus)
LAMBDA_BINARY_OPERATOR(&, BitwiseAnd)
LAMBDA_BINARY_OPERATOR(|, BitwiseOr)
LAMBDA_BINARY_OPERATOR(^, BitwiseXor)
LAMBDA_BINARY_OPERATOR(&=, CompoundAnd)
LAMBDA_BINARY_OPERATOR(|=, CompoundOr)
LAMBDA_BINARY_OPERATOR(^=, CompoundXor)
LAMBDA_BINARY_OPERATOR(&&, LogicalAnd)
LAMBDA_BINARY_OPERATOR(||, LogicalOr)
LAMBDA_BINARY_OPERATOR(<<, LeftShift)
LAMBDA_BINARY_OPERATOR(<<=, CompoundLeftShift)
LAMBDA_BINARY_OPERATOR(>>, RightShift)
LAMBDA_BINARY_OPERATOR(>>=, CompoundRightShift)
//LAMBDA_BINARY_OPERATOR(=, Assignment)
LAMBDA_BINARY_OPERATOR(==, Equals)
LAMBDA_BINARY_OPERATOR(!=, NotEqual)
LAMBDA_BINARY_OPERATOR(<, LessThan)
LAMBDA_BINARY_OPERATOR(>, GreaterThan)
LAMBDA_BINARY_OPERATOR(<=, LessThanOrEqualTo)
LAMBDA_BINARY_OPERATOR(>=, GreaterThanOrEqualTo)
<commit_msg>Bugfix: two separate Functor traits classes force both operator arguments to inherit Functor<commit_after>#include <type_traits>

namespace Lambda {
	using namespace std;

	struct Functor {};

	template<typename _Type>
	struct IsFree {
		static bool constexpr s_f = is_base_of<
			Functor,
			typename remove_cv<
				typename remove_reference<_Type>::type
				>::type
			>::value;
	};

	template<typename _Type>
	struct IsBound {
		static bool constexpr s_f = !is_base_of<
			Functor,
			typename remove_cv<
				typename remove_reference<_Type>::type
				>::type
			>::value;
	};

	template<typename _Type, bool _fFree = IsFree<_Type>::s_f>
	struct FunctorTraits;

	template<typename _Type>
	struct FunctorTraits<_Type, false> {
		static inline _Type Pass(_Type &&rr) {
			return rr;
		}
	};

	template<typename _Left, typename _Right, bool _fLeftFree = IsFree<_Left>::s_f, bool _fRightFree = IsFree<_Right>::s_f>
	struct FunctorTraits2;

	template<typename _Left, typename _Right>
	struct FunctorTraits2<_Left, _Right, true, false> {
		template<typename _FunctorClass>
		static inline _FunctorClass Build(_Left &&rrLeft, _Right &&rrRight) {
			return _FunctorClass((_Left&&)rrLeft, (_Right&&)rrRight);
		}
	};

	template<typename _Left, typename _Right>
	struct FunctorTraits2<_Left, _Right, false, true> {
		template<typename _FunctorClass>
		static inline _FunctorClass Build(_Left &&rrLeft, _Right &&rrRight) {
			return _FunctorClass((_Left&&)rrLeft, (_Right&&)rrRight);
		}
	};

	template<typename _Left, typename _Right>
	struct FunctorTraits2<_Left, _Right, true, true> {
		template<typename _FunctorClass>
		static inline _FunctorClass Build(_Left &&rrLeft, _Right &&rrRight) {
			return _FunctorClass((_Left&&)rrLeft, (_Right&&)rrRight);
		}
	};

	template<typename _Type>
	inline _Type Pass(_Type &&rr) {
		return rr;
	}

	template<unsigned int _i>
	struct Bind :
		public Functor
	{
		template<typename _First, typename... _Other>
		inline static auto Apply(_First&&, _Other&&... rrOther) -> decltype(Bind<_i - 1>::Apply(rrOther...)) {
			return Bind<_i - 1>::Apply(rrOther...);
		}

		template<typename... _Arguments>
		inline auto operator () (_Arguments&&... rrArguments) -> decltype(Bind<_i>::Apply(rrArguments...)) {
			return Bind<_i>::Apply(rrArguments...);
		}
	};

	template<>
	struct Bind<0> :
		public Functor
	{
		template<typename _Type, typename... _Other>
		inline static _Type &&Apply(_Type &&rr, _Other&&...) {
			return rr;
		}

		template<typename _Type, typename... _Other>
		inline _Type &&operator () (_Type &&rr, _Other&&...) {
			return rr;
		}
	};

#define LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Operand, bool _fBound = IsBound<_Operand>::s_f> \
	struct Name; \
	template<typename _Operand> \
	struct Name<_Operand, false> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(Operator(m_Operand(Arguments...))) { \
			return Operator(m_Operand(Arguments...)); \
		} \
	}; \
	template<typename _Operand> \
	struct Name<_Operand, true> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(Operator m_Operand) { \
			return Operator m_Operand; \
		} \
	};

#define LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Operand, bool _fBound = IsBound<_Operand>::s_f> \
	struct Name; \
	template<typename _Operand> \
	struct Name<_Operand, false> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype((m_Operand(Arguments...)) Operator) { \
			return (m_Operand(Arguments...)) Operator; \
		} \
	}; \
	template<typename _Operand> \
	struct Name<_Operand, true> : \
		public Functor \
	{ \
		_Operand m_Operand; \
		Name(_Operand &&a_rrOperand) \
			: \
		m_Operand(Pass(a_rrOperand)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(m_Operand Operator) { \
			return m_Operand Operator; \
		} \
	};

LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(+, UnaryPlus)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(-, UnaryMinus)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(!, LogicalNot)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(~, BitwiseNot)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(++, PreIncrement)
LAMBDA_PREFIX_UNARY_FUNCTOR_CLASS(--, PreDecrement)
LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(++, PostIncrement)
LAMBDA_POSTFIX_UNARY_FUNCTOR_CLASS(--, PostDecrement)

#define LAMBDA_BINARY_FUNCTOR_CLASS(Operator, Name) \
	template<typename _Left, typename _Right, bool _fLeftBound = IsBound<_Left>::s_f, bool _fRightBound = IsBound<_Right>::s_f> \
	struct Name; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, false, false> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left(Arguments...) Operator m_Right(Arguments...)) { \
			return m_Left(Arguments...) Operator m_Right(Arguments...); \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, true, false> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left Operator m_Right(Arguments...)) { \
			return m_Left Operator m_Right(Arguments...); \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, false, true> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&... Arguments) -> decltype(m_Left(Arguments...) Operator m_Right) { \
			return m_Left(Arguments...) Operator m_Right; \
		} \
	}; \
	template<typename _Left, typename _Right> \
	struct Name<_Left, _Right, true, true> : \
		public Functor \
	{ \
		_Left m_Left; \
		_Right m_Right; \
		Name(_Left &&a_rrLeft, _Right &&a_rrRight) \
			: \
		m_Left(Pass(a_rrLeft)), \
			m_Right(Pass(a_rrRight)) {} \
		template<typename... _Arguments> \
		inline auto operator () (_Arguments&&...) -> decltype(m_Left Operator m_Right) { \
			return m_Left Operator m_Right; \
		} \
	};

LAMBDA_BINARY_FUNCTOR_CLASS(+, BinaryPlus)
LAMBDA_BINARY_FUNCTOR_CLASS(+=, CompoundPlus)
LAMBDA_BINARY_FUNCTOR_CLASS(-, BinaryMinus)
LAMBDA_BINARY_FUNCTOR_CLASS(-=, CompoundMinus)
LAMBDA_BINARY_FUNCTOR_CLASS(*, Multiply)
LAMBDA_BINARY_FUNCTOR_CLASS(*=, CompoundMultiply)
LAMBDA_BINARY_FUNCTOR_CLASS(/, Divide)
LAMBDA_BINARY_FUNCTOR_CLASS(/=, CompoundDivide)
LAMBDA_BINARY_FUNCTOR_CLASS(%, Modulus)
LAMBDA_BINARY_FUNCTOR_CLASS(%=, CompoundModulus)
LAMBDA_BINARY_FUNCTOR_CLASS(&, BitwiseAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(|, BitwiseOr)
LAMBDA_BINARY_FUNCTOR_CLASS(^, BitwiseXor)
LAMBDA_BINARY_FUNCTOR_CLASS(&=, CompoundAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(|=, CompoundOr)
LAMBDA_BINARY_FUNCTOR_CLASS(^=, CompoundXor)
LAMBDA_BINARY_FUNCTOR_CLASS(&&, LogicalAnd)
LAMBDA_BINARY_FUNCTOR_CLASS(||, LogicalOr)
LAMBDA_BINARY_FUNCTOR_CLASS(<<, LeftShift)
LAMBDA_BINARY_FUNCTOR_CLASS(<<=, CompoundLeftShift)
LAMBDA_BINARY_FUNCTOR_CLASS(>>, RightShift)
LAMBDA_BINARY_FUNCTOR_CLASS(>>=, CompoundRightShift)
LAMBDA_BINARY_FUNCTOR_CLASS(=, Assignment)
LAMBDA_BINARY_FUNCTOR_CLASS(==, Equals)
LAMBDA_BINARY_FUNCTOR_CLASS(!=, NotEqual)
LAMBDA_BINARY_FUNCTOR_CLASS(<, LessThan)
LAMBDA_BINARY_FUNCTOR_CLASS(>, GreaterThan)
LAMBDA_BINARY_FUNCTOR_CLASS(<=, LessThanOrEqualTo)
LAMBDA_BINARY_FUNCTOR_CLASS(>=, GreaterThanOrEqualTo)

}

Lambda::Bind<0> _1;
Lambda::Bind<1> _2;
Lambda::Bind<2> _3;
Lambda::Bind<3> _4;
Lambda::Bind<4> _5;
Lambda::Bind<5> _6;
Lambda::Bind<6> _7;
Lambda::Bind<7> _8;
Lambda::Bind<8> _9;
Lambda::Bind<9> _10;

#define LAMBDA_PREFIX_UNARY_OPERATOR(Operator, FunctorClass) \
	template<typename _Operand, typename _Traits = Lambda::FunctorTraits<_Operand>> \
	inline Lambda::FunctorClass<_Operand> operator Operator (_Operand &&rrOperand) { \
		return Lambda::FunctorClass<_Operand>(_Traits::Pass(rrOperand)); \
	}

LAMBDA_PREFIX_UNARY_OPERATOR(+, UnaryPlus)
LAMBDA_PREFIX_UNARY_OPERATOR(-, UnaryMinus)
LAMBDA_PREFIX_UNARY_OPERATOR(!, LogicalNot)
LAMBDA_PREFIX_UNARY_OPERATOR(~, BitwiseNot)
LAMBDA_PREFIX_UNARY_OPERATOR(++, PreIncrement)
LAMBDA_PREFIX_UNARY_OPERATOR(--, PreDecrement)

#define LAMBDA_BINARY_OPERATOR(Operator, FunctorClass) \
	template<typename _Left, typename _Right, typename _Traits = Lambda::FunctorTraits2<_Left, _Right>> \
	inline Lambda::FunctorClass<_Left, _Right> operator Operator (_Left &&rrLeft, _Right &&rrRight) { \
		return _Traits::Build<typename Lambda::FunctorClass<_Left, _Right>>((_Left&&)rrLeft, (_Right&&)rrRight); \
	}

LAMBDA_BINARY_OPERATOR(+, BinaryPlus)
LAMBDA_BINARY_OPERATOR(+=, CompoundPlus)
LAMBDA_BINARY_OPERATOR(-, BinaryMinus)
LAMBDA_BINARY_OPERATOR(-=, CompoundMinus)
LAMBDA_BINARY_OPERATOR(*, Multiply)
LAMBDA_BINARY_OPERATOR(*=, CompoundMultiply)
LAMBDA_BINARY_OPERATOR(/, Divide)
LAMBDA_BINARY_OPERATOR(/=, CompoundDivide)
LAMBDA_BINARY_OPERATOR(%, Modulus)
LAMBDA_BINARY_OPERATOR(%=, CompoundModulus)
LAMBDA_BINARY_OPERATOR(&, BitwiseAnd)
LAMBDA_BINARY_OPERATOR(|, BitwiseOr)
LAMBDA_BINARY_OPERATOR(^, BitwiseXor)
LAMBDA_BINARY_OPERATOR(&=, CompoundAnd)
LAMBDA_BINARY_OPERATOR(|=, CompoundOr)
LAMBDA_BINARY_OPERATOR(^=, CompoundXor)
LAMBDA_BINARY_OPERATOR(&&, LogicalAnd)
LAMBDA_BINARY_OPERATOR(||, LogicalOr)
LAMBDA_BINARY_OPERATOR(<<, LeftShift)
LAMBDA_BINARY_OPERATOR(<<=, CompoundLeftShift)
LAMBDA_BINARY_OPERATOR(>>, RightShift)
LAMBDA_BINARY_OPERATOR(>>=, CompoundRightShift)
//LAMBDA_BINARY_OPERATOR(=, Assignment)
LAMBDA_BINARY_OPERATOR(==, Equals)
LAMBDA_BINARY_OPERATOR(!=, NotEqual)
LAMBDA_BINARY_OPERATOR(<, LessThan)
LAMBDA_BINARY_OPERATOR(>, GreaterThan)
LAMBDA_BINARY_OPERATOR(<=, LessThanOrEqualTo)
LAMBDA_BINARY_OPERATOR(>=, GreaterThanOrEqualTo)
<|endoftext|>


<commit_before>/*
===============================================================================

  FILE:  laszip.hpp

  CONTENTS:

    Contains LASitem and LASchunk structs as well as the IDs of the currently
    supported entropy coding scheme

  PROGRAMMERS:

    martin.isenburg@rapidlasso.com  -  http://rapidlasso.com

  COPYRIGHT:

    (c) 2007-2017, martin isenburg, rapidlasso - fast tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    28 May 2017 -- support for "LAS 1.4 selective decompression" added into DLL API
    8 April 2017 -- new check for whether point size and total size of items match
    30 March 2017 -- support for "native LAS 1.4 extension" added into main branch
    7 January 2017 -- set reserved VLR field from 0xAABB to 0x0 in DLL
    7 January 2017 -- consistent compatibility mode scan angle quantization in DLL
    7 January 2017 -- compatibility mode *decompression* fix for waveforms in DLL
    25 February 2016 -- depreciating old libLAS laszipper/lasunzipper binding
    29 July 2013 -- reorganized to create an easy-to-use LASzip DLL
    5 December 2011 -- learns the chunk table if it is missing (e.g. truncated LAZ)
    6 October 2011 -- large file support, ability to read with missing chunk table
    23 June 2011 -- turned on LASzip version 2.0 compressor with chunking
    8 May 2011 -- added an option for variable chunking via chunk()
    23 April 2011 -- changed interface for simplicity and chunking support
    20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
    10 January 2011 -- licensing change for LGPL release and liblas integration
    12 December 2010 -- refactored from lasdefinitions after movies with silke

===============================================================================
*/
#ifndef LASZIP_HPP
#define LASZIP_HPP

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define LZ_WIN32_VC6
typedef __int64   SIGNED_INT64;
#else
typedef long long SIGNED_INT64;
#endif

#if defined(_MSC_VER) && \
    (_MSC_FULL_VER >= 150000000)
#define LASCopyString _strdup
#else
#define LASCopyString strdup
#endif

#define LASZIP_VERSION_MAJOR                3
#define LASZIP_VERSION_MINOR                0
#define LASZIP_VERSION_REVISION             4
#define LASZIP_VERSION_BUILD_DATE      170804

#define LASZIP_COMPRESSOR_NONE              0
#define LASZIP_COMPRESSOR_POINTWISE         1
#define LASZIP_COMPRESSOR_POINTWISE_CHUNKED 2
#define LASZIP_COMPRESSOR_LAYERED_CHUNKED   3
#define LASZIP_COMPRESSOR_TOTAL_NUMBER_OF   4

#define LASZIP_COMPRESSOR_CHUNKED LASZIP_COMPRESSOR_POINTWISE_CHUNKED
#define LASZIP_COMPRESSOR_NOT_CHUNKED LASZIP_COMPRESSOR_POINTWISE

#define LASZIP_COMPRESSOR_DEFAULT LASZIP_COMPRESSOR_CHUNKED

#define LASZIP_CODER_ARITHMETIC             0
#define LASZIP_CODER_TOTAL_NUMBER_OF        1

#define LASZIP_CHUNK_SIZE_DEFAULT           50000

class LASitem
{
public:
  enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13, POINT14, RGB14, RGBNIR14, WAVEPACKET14, BYTE14 } type;
  unsigned short size;
  unsigned short version;
  bool is_type(LASitem::Type t) const;
  const char* get_name() const;
};

class LASzip
{
public:

  // supported version control
  bool check_compressor(const unsigned short compressor);
  bool check_coder(const unsigned short coder);
  bool check_item(const LASitem* item);
  bool check_items(const unsigned short num_items, const LASitem* items, const unsigned short point_size=0);
  bool check(const unsigned short point_size=0);

  // go back and forth between item array and point type & size
  bool setup(unsigned short* num_items, LASitem** items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE);
  bool is_standard(const unsigned short num_items, const LASitem* items, unsigned char* point_type=0, unsigned short* record_length=0);
  bool is_standard(unsigned char* point_type=0, unsigned short* record_length=0);

  // pack to and unpack from VLR
  unsigned char* bytes;
  bool unpack(const unsigned char* bytes, const int num);
  bool pack(unsigned char*& bytes, int& num);

  // setup
  bool request_compatibility_mode(const unsigned short requested_compatibility_mode=0); // 0 = none, 1 = LAS 1.4 compatibility mode
  bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
  bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor);
  bool set_chunk_size(const unsigned int chunk_size);             /* for compressor only */
  bool request_version(const unsigned short requested_version);   /* for compressor only */

  // in case a function returns false this string describes the problem
  const char* get_error() const;

  // stored in LASzip VLR data section
  unsigned short compressor;
  unsigned short coder;
  unsigned char version_major;
  unsigned char version_minor;
  unsigned short version_revision;
  unsigned int options;
  unsigned int chunk_size;
  SIGNED_INT64 number_of_special_evlrs; /* must be -1 if unused */
  SIGNED_INT64 offset_to_special_evlrs; /* must be -1 if unused */
  unsigned short num_items;
  LASitem* items;

  LASzip();
  ~LASzip();

private:
  bool return_error(const char* err);
  char* error_string;
};

#endif
<commit_msg>minor version increment (also for turning on 'native LAS 1.4 extension' by default<commit_after>/*
===============================================================================

  FILE:  laszip.hpp

  CONTENTS:

    Contains LASitem and LASchunk structs as well as the IDs of the currently
    supported entropy coding scheme

  PROGRAMMERS:

    martin.isenburg@rapidlasso.com  -  http://rapidlasso.com

  COPYRIGHT:

    (c) 2007-2017, martin isenburg, rapidlasso - fast tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    23 August 2017 -- minor version increment for C++ stream-based read/write API
    28 May 2017 -- support for "LAS 1.4 selective decompression" added into DLL API
    8 April 2017 -- new check for whether point size and total size of items match
    30 March 2017 -- support for "native LAS 1.4 extension" added into main branch
    7 January 2017 -- set reserved VLR field from 0xAABB to 0x0 in DLL
    7 January 2017 -- consistent compatibility mode scan angle quantization in DLL
    7 January 2017 -- compatibility mode *decompression* fix for waveforms in DLL
    25 February 2016 -- depreciating old libLAS laszipper/lasunzipper binding
    29 July 2013 -- reorganized to create an easy-to-use LASzip DLL
    5 December 2011 -- learns the chunk table if it is missing (e.g. truncated LAZ)
    6 October 2011 -- large file support, ability to read with missing chunk table
    23 June 2011 -- turned on LASzip version 2.0 compressor with chunking
    8 May 2011 -- added an option for variable chunking via chunk()
    23 April 2011 -- changed interface for simplicity and chunking support
    20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
    10 January 2011 -- licensing change for LGPL release and liblas integration
    12 December 2010 -- refactored from lasdefinitions after movies with silke

===============================================================================
*/
#ifndef LASZIP_HPP
#define LASZIP_HPP

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define LZ_WIN32_VC6
typedef __int64   SIGNED_INT64;
#else
typedef long long SIGNED_INT64;
#endif

#if defined(_MSC_VER) && \
    (_MSC_FULL_VER >= 150000000)
#define LASCopyString _strdup
#else
#define LASCopyString strdup
#endif

#define LASZIP_VERSION_MAJOR                3
#define LASZIP_VERSION_MINOR                1
#define LASZIP_VERSION_REVISION             0
#define LASZIP_VERSION_BUILD_DATE      170823

#define LASZIP_COMPRESSOR_NONE              0
#define LASZIP_COMPRESSOR_POINTWISE         1
#define LASZIP_COMPRESSOR_POINTWISE_CHUNKED 2
#define LASZIP_COMPRESSOR_LAYERED_CHUNKED   3
#define LASZIP_COMPRESSOR_TOTAL_NUMBER_OF   4

#define LASZIP_COMPRESSOR_CHUNKED LASZIP_COMPRESSOR_POINTWISE_CHUNKED
#define LASZIP_COMPRESSOR_NOT_CHUNKED LASZIP_COMPRESSOR_POINTWISE

#define LASZIP_COMPRESSOR_DEFAULT LASZIP_COMPRESSOR_CHUNKED

#define LASZIP_CODER_ARITHMETIC             0
#define LASZIP_CODER_TOTAL_NUMBER_OF        1

#define LASZIP_CHUNK_SIZE_DEFAULT           50000

class LASitem
{
public:
  enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13, POINT14, RGB14, RGBNIR14, WAVEPACKET14, BYTE14 } type;
  unsigned short size;
  unsigned short version;
  bool is_type(LASitem::Type t) const;
  const char* get_name() const;
};

class LASzip
{
public:

  // supported version control
  bool check_compressor(const unsigned short compressor);
  bool check_coder(const unsigned short coder);
  bool check_item(const LASitem* item);
  bool check_items(const unsigned short num_items, const LASitem* items, const unsigned short point_size=0);
  bool check(const unsigned short point_size=0);

  // go back and forth between item array and point type & size
  bool setup(unsigned short* num_items, LASitem** items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE);
  bool is_standard(const unsigned short num_items, const LASitem* items, unsigned char* point_type=0, unsigned short* record_length=0);
  bool is_standard(unsigned char* point_type=0, unsigned short* record_length=0);

  // pack to and unpack from VLR
  unsigned char* bytes;
  bool unpack(const unsigned char* bytes, const int num);
  bool pack(unsigned char*& bytes, int& num);

  // setup
  bool request_compatibility_mode(const unsigned short requested_compatibility_mode=0); // 0 = none, 1 = LAS 1.4 compatibility mode
  bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
  bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor);
  bool set_chunk_size(const unsigned int chunk_size);             /* for compressor only */
  bool request_version(const unsigned short requested_version);   /* for compressor only */

  // in case a function returns false this string describes the problem
  const char* get_error() const;

  // stored in LASzip VLR data section
  unsigned short compressor;
  unsigned short coder;
  unsigned char version_major;
  unsigned char version_minor;
  unsigned short version_revision;
  unsigned int options;
  unsigned int chunk_size;
  SIGNED_INT64 number_of_special_evlrs; /* must be -1 if unused */
  SIGNED_INT64 offset_to_special_evlrs; /* must be -1 if unused */
  unsigned short num_items;
  LASitem* items;

  LASzip();
  ~LASzip();

private:
  bool return_error(const char* err);
  char* error_string;
};

#endif
<|endoftext|>


<commit_before>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/sfm/sfm.hpp"
#include "openMVG/system/timer.hpp"

#include "third_party/cmdLine/cmdLine.h"
#include "third_party/stlplus3/filesystemSimplified/file_system.hpp"

using namespace openMVG;
using namespace openMVG::sfm;

/// Compute the structure of a scene according existing camera poses.
int main(int argc, char **argv)
{
  using namespace std;
  std::cout << "Compute Structure from the provided poses" << std::endl;

  CmdLine cmd;

  std::string sSfM_Data_Filename;
  std::string sFeaturesDir;
  std::string sMatchesDir;
  std::string sMatchesGeometricModel = "f";
  std::string sOutFile = "";

  cmd.add( make_option('i', sSfM_Data_Filename, "input_file") );
  cmd.add( make_option('f', sFeaturesDir, "feat_dir") );
  cmd.add( make_option('m', sMatchesDir, "match_dir") );
  cmd.add( make_option('o', sOutFile, "output_file") );
  cmd.add( make_option('g', sMatchesGeometricModel, "matchesGeometricModel"));

  try {
    if (argc == 1) throw std::string("Invalid command line parameter.");
    cmd.process(argc, argv);
  } catch(const std::string& s) {
    std::cerr << "Usage: " << argv[0] << "\n"
       "[-i|--input_file] path to a SfM_Data scene\n"
       "[-o|--output_file] file where the output data will be stored "
          "(i.e. path/sfm_data_structure.bin)\n"
       "[-m|--feat_dir] path to the features and descriptors that "
          "corresponds to the provided SfM_Data scene\n"
       "\n[Optional]\n"
       "[-m|--match_dir] path to the matches files "
       "(if not provided the images connections will be computed from Frustrums intersections)\n"
       "[-g|--matchesGeometricModel MODEL] matching geometric model used: 'f' (default), 'e' or 'h'"
    << std::endl;

    std::cerr << s << std::endl;
    return EXIT_FAILURE;
  }

  // Load input SfM_Data scene
  SfM_Data sfm_data;
  if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS|EXTRINSICS))) {
    std::cerr << std::endl
      << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read." << std::endl;
    return EXIT_FAILURE;
  }

  // Init the regions_type from the image describer file (used for image regions extraction)
  using namespace openMVG::features;
  const std::string sImage_describer = stlplus::create_filespec(sFeaturesDir, "image_describer", "json");
  std::unique_ptr<Regions> regions_type = Init_region_type_from_file(sImage_describer);
  if (!regions_type)
  {
    std::cerr << "Invalid: "
      << sImage_describer << " regions type file." << std::endl;
    return EXIT_FAILURE;
  }

  // Prepare the Regions provider
  std::shared_ptr<Regions_Provider> regions_provider = std::make_shared<Regions_Provider>();
  if (!regions_provider->load(sfm_data, sFeaturesDir, regions_type)) {
    std::cerr << std::endl
      << "Invalid regions." << std::endl;
    return EXIT_FAILURE;
  }

  //--
  //- Pair selection method:
  //  - geometry guided -> camera frustum intersection,
  //  - putative matches guided (photometric matches)
  //     (keep pairs that have valid Intrinsic & Pose ids).
  //--
  Pair_Set pairs;
  if (sMatchesDir.empty())
  {
    // No image pair provided, so we use cameras frustum intersection.
    // Build the list of connected images pairs from frustum intersections
    pairs = Frustum_Filter(sfm_data).getFrustumIntersectionPairs();
  }
  else
  {
    // Load pre-computed matches
    PairWiseMatches matches;
    if (!matching::Load(matches, sfm_data.GetViewsKeys(), sMatchesDir, sMatchesGeometricModel))
    {
      std::cerr<< "Unable to read the matches file." << std::endl;
      return EXIT_FAILURE;
    }
    pairs = getPairs(matches);
    // Keep only Pairs that belong to valid view indexes.
    const std::set<IndexT> valid_viewIdx = Get_Valid_Views(sfm_data);
    pairs = Pair_filter(pairs, valid_viewIdx);
  }

  openMVG::system::Timer timer;

  // Clear previous 3D landmarks
  sfm_data.structure.clear();

  //------------------------------------------
  // Compute Structure from known camera poses
  //------------------------------------------
  SfM_Data_Structure_Estimation_From_Known_Poses structure_estimator;
  structure_estimator.match(sfm_data, pairs, regions_provider);

  // Unload descriptors before triangulation
  regions_provider->clearDescriptors();

  // Filter matches
  structure_estimator.filter(sfm_data, pairs, regions_provider);
  // Create 3D landmarks
  structure_estimator.triangulate(sfm_data, regions_provider);

  RemoveOutliers_AngleError(sfm_data, 2.0);

  std::cout
    << "\nStructure estimation took (s): " << timer.elapsed() << "." << std::endl
    << "#landmark found: " << sfm_data.GetLandmarks().size() << std::endl;

  if (stlplus::extension_part(sOutFile) != "ply") {
    Save(sfm_data,
      stlplus::create_filespec(
        stlplus::folder_part(sOutFile),
        stlplus::basename_part(sOutFile), "ply"),
      ESfM_Data(ALL));
  }

  if (Save(sfm_data, sOutFile, ESfM_Data(ALL)))
    return EXIT_SUCCESS;

  std::cout << "Error while saving the sfm data!" << std::endl;
  return EXIT_FAILURE;
}
<commit_msg>[software] fix command line argument name<commit_after>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "openMVG/sfm/sfm.hpp"
#include "openMVG/system/timer.hpp"

#include "third_party/cmdLine/cmdLine.h"
#include "third_party/stlplus3/filesystemSimplified/file_system.hpp"

using namespace openMVG;
using namespace openMVG::sfm;

/// Compute the structure of a scene according existing camera poses.
int main(int argc, char **argv)
{
  using namespace std;
  std::cout << "Compute Structure from the provided poses" << std::endl;

  CmdLine cmd;

  std::string sSfM_Data_Filename;
  std::string sFeaturesDir;
  std::string sMatchesDir;
  std::string sMatchesGeometricModel = "f";
  std::string sOutFile = "";

  cmd.add( make_option('i', sSfM_Data_Filename, "input_file") );
  cmd.add( make_option('f', sFeaturesDir, "feat_dir") );
  cmd.add( make_option('m', sMatchesDir, "match_dir") );
  cmd.add( make_option('o', sOutFile, "output_file") );
  cmd.add( make_option('g', sMatchesGeometricModel, "matchesGeometricModel"));

  try {
    if (argc == 1) throw std::string("Invalid command line parameter.");
    cmd.process(argc, argv);
  } catch(const std::string& s) {
    std::cerr << "Usage: " << argv[0] << "\n"
       "[-i|--input_file] path to a SfM_Data scene\n"
       "[-o|--output_file] file where the output data will be stored "
          "(i.e. path/sfm_data_structure.bin)\n"
       "[-f|--feat_dir] path to the features and descriptors that "
          "corresponds to the provided SfM_Data scene\n"
       "\n[Optional]\n"
       "[-m|--match_dir] path to the matches files "
       "(if not provided the images connections will be computed from Frustrums intersections)\n"
       "[-g|--matchesGeometricModel MODEL] matching geometric model used: 'f' (default), 'e' or 'h'"
    << std::endl;

    std::cerr << s << std::endl;
    return EXIT_FAILURE;
  }

  // Load input SfM_Data scene
  SfM_Data sfm_data;
  if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS|EXTRINSICS))) {
    std::cerr << std::endl
      << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read." << std::endl;
    return EXIT_FAILURE;
  }

  // Init the regions_type from the image describer file (used for image regions extraction)
  using namespace openMVG::features;
  const std::string sImage_describer = stlplus::create_filespec(sFeaturesDir, "image_describer", "json");
  std::unique_ptr<Regions> regions_type = Init_region_type_from_file(sImage_describer);
  if (!regions_type)
  {
    std::cerr << "Invalid: "
      << sImage_describer << " regions type file." << std::endl;
    return EXIT_FAILURE;
  }

  // Prepare the Regions provider
  std::shared_ptr<Regions_Provider> regions_provider = std::make_shared<Regions_Provider>();
  if (!regions_provider->load(sfm_data, sFeaturesDir, regions_type)) {
    std::cerr << std::endl
      << "Invalid regions." << std::endl;
    return EXIT_FAILURE;
  }

  //--
  //- Pair selection method:
  //  - geometry guided -> camera frustum intersection,
  //  - putative matches guided (photometric matches)
  //     (keep pairs that have valid Intrinsic & Pose ids).
  //--
  Pair_Set pairs;
  if (sMatchesDir.empty())
  {
    // No image pair provided, so we use cameras frustum intersection.
    // Build the list of connected images pairs from frustum intersections
    pairs = Frustum_Filter(sfm_data).getFrustumIntersectionPairs();
  }
  else
  {
    // Load pre-computed matches
    PairWiseMatches matches;
    if (!matching::Load(matches, sfm_data.GetViewsKeys(), sMatchesDir, sMatchesGeometricModel))
    {
      std::cerr<< "Unable to read the matches file." << std::endl;
      return EXIT_FAILURE;
    }
    pairs = getPairs(matches);
    // Keep only Pairs that belong to valid view indexes.
    const std::set<IndexT> valid_viewIdx = Get_Valid_Views(sfm_data);
    pairs = Pair_filter(pairs, valid_viewIdx);
  }

  openMVG::system::Timer timer;

  // Clear previous 3D landmarks
  sfm_data.structure.clear();

  //------------------------------------------
  // Compute Structure from known camera poses
  //------------------------------------------
  SfM_Data_Structure_Estimation_From_Known_Poses structure_estimator;
  structure_estimator.match(sfm_data, pairs, regions_provider);

  // Unload descriptors before triangulation
  regions_provider->clearDescriptors();

  // Filter matches
  structure_estimator.filter(sfm_data, pairs, regions_provider);
  // Create 3D landmarks
  structure_estimator.triangulate(sfm_data, regions_provider);

  RemoveOutliers_AngleError(sfm_data, 2.0);

  std::cout
    << "\nStructure estimation took (s): " << timer.elapsed() << "." << std::endl
    << "#landmark found: " << sfm_data.GetLandmarks().size() << std::endl;

  if (stlplus::extension_part(sOutFile) != "ply") {
    Save(sfm_data,
      stlplus::create_filespec(
        stlplus::folder_part(sOutFile),
        stlplus::basename_part(sOutFile), "ply"),
      ESfM_Data(ALL));
  }

  if (Save(sfm_data, sOutFile, ESfM_Data(ALL)))
    return EXIT_SUCCESS;

  std::cout << "Error while saving the sfm data!" << std::endl;
  return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2006 Soeren Sonnenburg
 * Written (W) 1999-2006 Gunnar Raetsch
 * Copyright (C) 1999-2006 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "lib/config.h"

#ifdef HAVE_OCTAVE
#include <octave/config.h>
#include <octave/error.h>
#include <octave/lo-error.h>
#endif

#ifdef HAVE_MATLAB
#include <mex.h>
#endif

#ifdef HAVE_PYTHON
#include <Python.h>
#endif

#ifdef HAVE_R
#include <R.h>
#include <Rinternals.h>
#include <R_ext/RS.h>
#endif

#include "lib/io.h"
#include "lib/Signal.h"
#include "lib/common.h"
#include "lib/Time.h"
#include "lib/Mathematics.h"

#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>

FILE* CIO::target=stdout;
LONG CIO::last_progress_time=0 ;
LONG CIO::progress_start_time=0 ;
DREAL CIO::last_progress=1 ;
EMessageType CIO::loglevel = M_WARN;
const EMessageType CIO::levels[NUM_LOG_LEVELS]={M_DEBUG, M_INFO, M_NOTICE, M_WARN, M_ERROR, M_CRITICAL, M_ALERT, M_EMERGENCY,M_MESSAGEONLY};
const char* CIO::message_strings[NUM_LOG_LEVELS]={"[DEBUG] ", "[INFO] ", "[NOTICE] ", "\033[1;34m[WARN]\033[0m ", "\033[1;31m[ERROR]\033[0m ", "[CRITICAL] ", "[ALERT] ", "[EMERGENCY] ", ""};

CIO::CIO()
{
}

void CIO::message(EMessageType prio, const CHAR *fmt, ... )
{
#if defined(HAVE_MATLAB) || defined(HAVE_PYTHON) || defined(HAVE_OCTAVE) || defined(HAVE_R)
	char str[4096];
    va_list list;
    va_start(list,fmt);
	vsnprintf(str, sizeof(str), fmt, list);
    va_end(list);

	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
#ifdef HAVE_MATLAB
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				mexWarnMsgTxt(str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				CSignal::unset_handler();
				mexErrMsgTxt(str);
				break;
			default:
				break;
		}
#elif defined(HAVE_OCTAVE)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				::warning(str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				CSignal::unset_handler();
				error("%s", str);
				break;
			default:
				break;
		}
#elif defined(HAVE_PYTHON)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				PyErr_Warn(NULL, str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				PyErr_SetString(PyExc_RuntimeError,str);
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;
			default:
				break;
		}
#elif defined(HAVE_R)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
			case M_WARN:
				{
					int p=get_prio_string(prio);

					if (p>=0)
					{
						Rprintf("%s",message_strings[p]);
						va_list list;
						va_start(list,fmt);
						Rvprintf(fmt,list);
						va_end(list);
					}
				}
				break;
			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				error("%s", str);
				break;
			default:
				break;
		}

#endif
		fflush(target);
	}
#else
	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
		fprintf(target, message_strings[p]);
		va_list list;
		va_start(list,fmt);
		vfprintf(target,fmt,list);
		va_end(list);
		fflush(target);
	}
#endif
}

void CIO::buffered_message(EMessageType prio, const CHAR *fmt, ... )
{
	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
		fprintf(target, message_strings[p]);
		va_list list;
		va_start(list,fmt);
		vfprintf(target,fmt,list);
		va_end(list);
	}
}

void CIO::progress(DREAL current_val, DREAL min_val, DREAL max_val, INT decimals, const char* prefix)
{
	LONG runtime = CTime::get_runtime() ;

	char str[1000];
	DREAL v=-1, estimate=0, total_estimate=0 ;
	check_target();
	//min_val=0.0 ;

	fprintf(stderr, "min_val=%f\n", min_val) ;
	fprintf(stderr, "max_val=%f\n", max_val) ;

	if (max_val-min_val>0.0)
		v=100*(current_val-min_val+1)/(max_val-min_val+1);

	if (decimals < 1)
		decimals = 1;

	if (last_progress>v)
	{
		last_progress_time = runtime ;
		progress_start_time = runtime;
		last_progress = v ;
	}
	else
	{
		if (v>100) v=100.0 ;
		if (v<=0) v=1e-6 ;
		last_progress = v-1e-5 ; ;

		if ((v!=100.0) && (runtime - last_progress_time<100))
			return ;

		last_progress_time = runtime ;
		estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100) ;
		total_estimate = (last_progress_time-progress_start_time)/(v/100) ;
	}

	if (estimate/100>120)
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, v, (float)estimate/100/60, (float)total_estimate/100/60);
	}
	else
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, v, (float)estimate/100, (float)total_estimate/100);
	}

    fflush(target);
}

void CIO::absolute_progress(DREAL current_val, DREAL val, DREAL min_val, DREAL max_val, INT decimals, const char* prefix)
{
	LONG runtime = CTime::get_runtime() ;

	char str[1000];
	DREAL v=-1, estimate=0, total_estimate=0 ;
	check_target();

	if (max_val-min_val>0)
		v=100*(val-min_val+1)/(max_val-min_val+1);

	if (decimals < 1)
		decimals = 1;

	if (last_progress>v)
	{
		last_progress_time = runtime ;
		progress_start_time = runtime;
		last_progress = v ;
	}
	else
	{
		if (v>100) v=100.0 ;
		if (v<=0) v=1e-6 ;
		last_progress = v-1e-5 ; ;

		if ((v!=100.0) && (runtime - last_progress_time<100))
			return ;

		last_progress_time = runtime ;
		estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100) ;
		total_estimate = (last_progress_time-progress_start_time)/(v/100) ;
	}

	if (estimate/100>120)
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, current_val, (float)estimate/100/60, (float)total_estimate/100/60);
	}
	else
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, current_val, (float)estimate/100, (float)total_estimate/100);
	}

    fflush(target);
}

CHAR* CIO::skip_spaces(CHAR* str)
{
	INT i=0;

	if (str)
	{
		for (i=0; isspace(str[i]); i++);

		return &str[i];
	}
	else
		return str;
}

void CIO::set_loglevel(EMessageType level)
{
	loglevel=level;
}

void CIO::set_target(FILE* t)
{
	target=t;
}

void CIO::check_target()
{
	if (!target)
		target=stdout;
}

int CIO::get_prio_string(EMessageType prio)
{
	int i=0;
	int idx=-1;

	while (i<NUM_LOG_LEVELS)
	{
		if (levels[i]==loglevel)
		{
			while (i<NUM_LOG_LEVELS)
			{
				if (levels[i]==prio)
				{
					idx=i;
					break;
				}
				i++;
			}
			break;
		}
		i++;
	}

	return idx;
}
<commit_msg>*** empty log message ***<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2006 Soeren Sonnenburg
 * Written (W) 1999-2006 Gunnar Raetsch
 * Copyright (C) 1999-2006 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include "lib/config.h"

#ifdef HAVE_OCTAVE
#include <octave/config.h>
#include <octave/error.h>
#include <octave/lo-error.h>
#endif

#ifdef HAVE_MATLAB
#include <mex.h>
#endif

#ifdef HAVE_PYTHON
#include <Python.h>
#endif

#ifdef HAVE_R
#include <R.h>
#include <Rinternals.h>
#include <R_ext/RS.h>
#endif

#include "lib/io.h"
#include "lib/Signal.h"
#include "lib/common.h"
#include "lib/Time.h"
#include "lib/Mathematics.h"

#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>

FILE* CIO::target=stdout;
LONG CIO::last_progress_time=0 ;
LONG CIO::progress_start_time=0 ;
DREAL CIO::last_progress=1 ;
EMessageType CIO::loglevel = M_WARN;
const EMessageType CIO::levels[NUM_LOG_LEVELS]={M_DEBUG, M_INFO, M_NOTICE, M_WARN, M_ERROR, M_CRITICAL, M_ALERT, M_EMERGENCY,M_MESSAGEONLY};
const char* CIO::message_strings[NUM_LOG_LEVELS]={"[DEBUG] ", "[INFO] ", "[NOTICE] ", "\033[1;34m[WARN]\033[0m ", "\033[1;31m[ERROR]\033[0m ", "[CRITICAL] ", "[ALERT] ", "[EMERGENCY] ", ""};

CIO::CIO()
{
}

void CIO::message(EMessageType prio, const CHAR *fmt, ... )
{
#if defined(HAVE_MATLAB) || defined(HAVE_PYTHON) || defined(HAVE_OCTAVE) || defined(HAVE_R)
	char str[4096];
    va_list list;
    va_start(list,fmt);
	vsnprintf(str, sizeof(str), fmt, list);
    va_end(list);

	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
#ifdef HAVE_MATLAB
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				mexWarnMsgTxt(str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				CSignal::unset_handler();
				mexErrMsgTxt(str);
				break;
			default:
				break;
		}
#elif defined(HAVE_OCTAVE)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				::warning(str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				CSignal::unset_handler();
				error("%s", str);
				break;
			default:
				break;
		}
#elif defined(HAVE_PYTHON)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;

			case M_WARN:
				PyErr_Warn(NULL, str);
				break;

			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				PyErr_SetString(PyExc_RuntimeError,str);
				fprintf(target, message_strings[p]);
				fprintf(target, "%s", str);
				break;
			default:
				break;
		}
#elif defined(HAVE_R)
		switch (prio)
		{
			case M_DEBUG:
			case M_INFO:
			case M_NOTICE:
			case M_MESSAGEONLY:
			case M_WARN:
				{
					int p=get_prio_string(prio);

					if (p>=0)
					{
						Rprintf("%s",message_strings[p]);
						va_list list;
						va_start(list,fmt);
						Rvprintf(fmt,list);
						va_end(list);
					}
				}
				break;
			case M_ERROR:
			case M_CRITICAL:
			case M_ALERT:
			case M_EMERGENCY:
				error("%s", str);
				break;
			default:
				break;
		}

#endif
		fflush(target);
	}
#else
	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
		fprintf(target, message_strings[p]);
		va_list list;
		va_start(list,fmt);
		vfprintf(target,fmt,list);
		va_end(list);
		fflush(target);
	}
#endif
}

void CIO::buffered_message(EMessageType prio, const CHAR *fmt, ... )
{
	check_target();
	int p=get_prio_string(prio);
	if (p>=0)
	{
		fprintf(target, message_strings[p]);
		va_list list;
		va_start(list,fmt);
		vfprintf(target,fmt,list);
		va_end(list);
	}
}

void CIO::progress(DREAL current_val, DREAL min_val, DREAL max_val, INT decimals, const char* prefix)
{
	LONG runtime = CTime::get_runtime() ;

	char str[1000];
	DREAL v=-1, estimate=0, total_estimate=0 ;
	check_target();
	//min_val=0.0 ;

	//fprintf(stderr, "min_val=%f\n", min_val) ;
	//fprintf(stderr, "max_val=%f\n", max_val) ;

	if (max_val-min_val>0.0)
		v=100*(current_val-min_val+1)/(max_val-min_val+1);

	if (decimals < 1)
		decimals = 1;

	if (last_progress>v)
	{
		last_progress_time = runtime ;
		progress_start_time = runtime;
		last_progress = v ;
	}
	else
	{
		if (v>100) v=100.0 ;
		if (v<=0) v=1e-6 ;
		last_progress = v-1e-5 ; ;

		if ((v!=100.0) && (runtime - last_progress_time<100))
			return ;

		last_progress_time = runtime ;
		estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100) ;
		total_estimate = (last_progress_time-progress_start_time)/(v/100) ;
	}

	if (estimate/100>120)
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, v, (float)estimate/100/60, (float)total_estimate/100/60);
	}
	else
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, v, (float)estimate/100, (float)total_estimate/100);
	}

    fflush(target);
}

void CIO::absolute_progress(DREAL current_val, DREAL val, DREAL min_val, DREAL max_val, INT decimals, const char* prefix)
{
	LONG runtime = CTime::get_runtime() ;

	char str[1000];
	DREAL v=-1, estimate=0, total_estimate=0 ;
	check_target();

	if (max_val-min_val>0)
		v=100*(val-min_val+1)/(max_val-min_val+1);

	if (decimals < 1)
		decimals = 1;

	if (last_progress>v)
	{
		last_progress_time = runtime ;
		progress_start_time = runtime;
		last_progress = v ;
	}
	else
	{
		if (v>100) v=100.0 ;
		if (v<=0) v=1e-6 ;
		last_progress = v-1e-5 ; ;

		if ((v!=100.0) && (runtime - last_progress_time<100))
			return ;

		last_progress_time = runtime ;
		estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100) ;
		total_estimate = (last_progress_time-progress_start_time)/(v/100) ;
	}

	if (estimate/100>120)
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, current_val, (float)estimate/100/60, (float)total_estimate/100/60);
	}
	else
	{
		snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
		message(M_MESSAGEONLY, str, prefix, current_val, (float)estimate/100, (float)total_estimate/100);
	}

    fflush(target);
}

CHAR* CIO::skip_spaces(CHAR* str)
{
	INT i=0;

	if (str)
	{
		for (i=0; isspace(str[i]); i++);

		return &str[i];
	}
	else
		return str;
}

void CIO::set_loglevel(EMessageType level)
{
	loglevel=level;
}

void CIO::set_target(FILE* t)
{
	target=t;
}

void CIO::check_target()
{
	if (!target)
		target=stdout;
}

int CIO::get_prio_string(EMessageType prio)
{
	int i=0;
	int idx=-1;

	while (i<NUM_LOG_LEVELS)
	{
		if (levels[i]==loglevel)
		{
			while (i<NUM_LOG_LEVELS)
			{
				if (levels[i]==prio)
				{
					idx=i;
					break;
				}
				i++;
			}
			break;
		}
		i++;
	}

	return idx;
}
<|endoftext|>


<commit_before>// Standard includes
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <inttypes.h>
#include <fstream>
#include <vector>
#include <sys/time.h>

// Serial includes
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#
#ifdef __linux
#include <sys/ioctl.h>
#endif

#include "planner_commander.h"

using std::string;
using std::vector;
using std::pair;
using namespace std;

int test_num = 0;

#define GRID_ROWS 20
#define GRID_COLS 20

#define CELL_WIDTH 10.0

// variables to keep track of state information
uint8_t grid[GRID_ROWS][GRID_COLS] = {{0}};			// grid of the world, not sure if needed???

vector<pair<int, int>> cells_visited;			// vector of pairs defining which grid cells have been visited
vector<double> observed_bearings;				// vector of bearing observations from each location visited
vector<int> observed_rssi;						// vector of max rssi observations from each location visited

pair<int, int> prev_commanded_grid_cell;			// the index of the previously commanded grid cell
pair<int, int> commanded_grid_cell;				// the index of the commanded grid cell

pair<float, float> get_next_pomdp_action(double &bearing, int &rssi) {

	// update the observation states
	update_observations(bearing, rssi);

	// update which is the next grid cell we want to go to
	update_next_commanded_cell();

	// convert the grid cell changes to actual distances
	float d_south = (float)(commanded_grid_cell.first - prev_commanded_grid_cell.first) * CELL_WIDTH;		// note rows increase SOUTH!!!
	float d_east = (float)(commanded_grid_cell.second - prev_commanded_grid_cell.second) * CELL_WIDTH;		// cols increase EAST

	// return the pair that contains the delta information
	return pair<float, float>(-d_south, d_east);
}

void update_observations(double &bearing, int &rssi) {

	// note that we have just visited the commanded grid cell
	cells_visited.push_back(commanded_grid_cell);

	// add the observed bearing and rssi to the list
	observed_bearings.push_back(bearing);
	observed_rssi.push_back(rssi);

	return;
}

void update_next_commanded_cell() {

	// TODO: do the actual pomdp stuff given the observations information

	// update the previous commanded grid cell index
	prev_commanded_grid_cell = commanded_grid_cell;

	// for now, just increase the indices
	// increase the row, until end of a row, and then increase the column
	if (commanded_grid_cell.first++ >=  GRID_ROWS) {
		commanded_grid_cell.first = 0;

		if (commanded_grid_cell.second++ >= GRID_COLS) {
			commanded_grid_cell.second = 0;
		}

	}

}
<commit_msg>add some comments<commit_after>// Standard includes
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <inttypes.h>
#include <fstream>
#include <vector>
#include <sys/time.h>

// Serial includes
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#
#ifdef __linux
#include <sys/ioctl.h>
#endif

#include "planner_commander.h"

using std::string;
using std::vector;
using std::pair;
using namespace std;

int test_num = 0;

#define GRID_ROWS 20
#define GRID_COLS 20

#define CELL_WIDTH 10.0

// variables to keep track of state information
uint8_t grid[GRID_ROWS][GRID_COLS] = {{0}};			// grid of the world, not sure if needed???

vector<pair<int, int>> cells_visited;			// vector of pairs defining which grid cells have been visited
vector<double> observed_bearings;				// vector of bearing observations from each location visited
vector<int> observed_rssi;						// vector of max rssi observations from each location visited

pair<int, int> prev_commanded_grid_cell;			// the index of the previously commanded grid cell
pair<int, int> commanded_grid_cell;				// the index of the commanded grid cell

// TODO: put additional global variables here needed to keep track of any styate information desired

pair<float, float> get_next_pomdp_action(double &bearing, int &rssi) {

	// update the observation states
	update_observations(bearing, rssi);

	// update which is the next grid cell we want to go to
	update_next_commanded_cell();

	// convert the grid cell changes to actual distances
	float d_south = (float)(commanded_grid_cell.first - prev_commanded_grid_cell.first) * CELL_WIDTH;		// note rows increase SOUTH!!!
	float d_east = (float)(commanded_grid_cell.second - prev_commanded_grid_cell.second) * CELL_WIDTH;		// cols increase EAST

	// return the pair that contains the delta information
	return pair<float, float>(-d_south, d_east);
}

void update_observations(double &bearing, int &rssi) {

	// TODO: add any additional update information that would be required

	// note that we have just visited the commanded grid cell
	cells_visited.push_back(commanded_grid_cell);

	// add the observed bearing and rssi to the list
	observed_bearings.push_back(bearing);
	observed_rssi.push_back(rssi);

	return;
}

void update_next_commanded_cell() {

	// TODO: do the actual pomdp stuff given the observations information

	// update the previous commanded grid cell index
	prev_commanded_grid_cell = commanded_grid_cell;

	// for now, just increase the indices
	// increase the row, until end of a row, and then increase the column
	if (commanded_grid_cell.first++ >=  GRID_ROWS) {
		commanded_grid_cell.first = 0;

		if (commanded_grid_cell.second++ >= GRID_COLS) {
			commanded_grid_cell.second = 0;
		}

	}

}
<|endoftext|>


<commit_before>/**
 *  Inline variables
 *  ================
 *
 *  Use inline keyword to define an external linkage const namespace scope
 *  variable, or any static class data member, in a header file, so that
 *  the multiple definitions that result when that header is included in
 *  multiple translation units are okay with the linker - it just chooses
 *  *one* of them.
 *
 *  Note: Compile with -std=c++17.
 */

#include <iostream>

int
main(int argc, const char *argv[])
{
    // TODO
    return 0;
}
<commit_msg>updated inline var but it seems uncompilable (due to c++17 and insufficient g++ version)<commit_after>/**
 *  Inline variables
 *  ================
 *
 *  Use inline keyword to define an external linkage const namespace scope
 *  variable, or any static class data member, in a header file, so that
 *  the multiple definitions that result when that header is included in
 *  multiple translation units are okay with the linker - it just chooses
 *  *one* of them.
 *
 *  Note: Compile with -std=c++17.
 *
 *  XXX: This seems not compilable on my g++ 5.4.0.
 */

#include <iostream>

/// Until C++17, it can be done via this trick with template.
template<class Dummy>
struct _Foo {
    static std::string hi;
};

/// Static member variable should be initialized outside the class.
template<class Dummy>
std::string _Foo<Dummy>::hi = "Hi! I'm Foo.";

/// Type alias via using was introduced since C++11.
using Foo = _Foo<void>; // `Foo::hi' is now allowed

/// Use the inline variable outside the class.
struct Bar {
    static std::string const hi = "Hi! I'm Bar.";
};

inline std::string Bar::hi = "Hi! I'm Bar.";

/// It can also be defined in the class definition.
struct Baz {
    static inline std::string hi = "Hi! I'm Baz.";
};

int
main(int argc, const char *argv[])
{
    std::cout << Foo::hi << std::endl;
    std::cout << Bar::hi << std::endl;
    std::cout << Baz::hi << std::endl;

    return 0;
}
<|endoftext|>