text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef LIBP2P_CONNECTION_STATE_HPP
#define LIBP2P_CONNECTION_STATE_HPP

#include <functional>
#include <memory>

#include <boost/asio/streambuf.hpp>
#include <gsl/span>
#include <libp2p/basic/readwriter.hpp>
#include <libp2p/common/types.hpp>
#include <libp2p/protocol_muxer/multiselect/multiselect_error.hpp>
#include <libp2p/protocol_muxer/protocol_muxer.hpp>

namespace libp2p::protocol_muxer {
  class Multiselect;
  using ByteArray = libp2p::common::ByteArray;

  /**
   * Stores current state of protocol negotiation over the connection
   */
  struct ConnectionState : std::enable_shared_from_this<ConnectionState> {
    enum class NegotiationStatus {
      NOTHING_SENT,
      OPENING_SENT,
      PROTOCOL_SENT,
      PROTOCOLS_SENT,
      LS_SENT,
      NA_SENT
    };

    /// connection, over which we are negotiating
    std::shared_ptr<basic::ReadWriter> connection;

    /// protocols to be selected
    std::shared_ptr<std::vector<peer::Protocol>> protocols;

    /// protocols, which were left for negotiation (if send one of the protocols
    /// and receive NA, it's removed from this queue)
    std::shared_ptr<std::vector<peer::Protocol>> left_protocols;

    /// callback, which is to be called, when a protocol is established over the
    /// connection
    ProtocolMuxer::ProtocolHandlerFunc proto_callback;

    /// write buffer of this connection
    std::shared_ptr<ByteArray> write_buffer;

    /// read buffer of this connection
    std::shared_ptr<boost::asio::streambuf> read_buffer;

    /// index of both buffers in Multiselect collection
    size_t buffers_index;

    /// Multiselect instance, which spawned this connection state
    std::shared_ptr<Multiselect> multiselect;

    /// current status of the negotiation
    NegotiationStatus status = NegotiationStatus::NOTHING_SENT;

    /**
     * Write to the underlying connection or stream
     * @param handler to be called, when the write is done
     * @note the function expects data to be written in the local write buffer
     */
    void write(basic::Writer::WriteCallbackFunc handler) {
      connection->write(*write_buffer, write_buffer->size(),
                        std::move(handler));
    }

    /**
     * Read from the underlying connection or stream
     * @param n - how much bytes to read
     * @param handler to be called, when the read is done
     * @note resul of read is going to be in the local read buffer
     */
    void read(size_t n,
              std::function<void(const outcome::result<void> &)> handler) {
      // if there are already enough bytes in our buffer, return them
      if (read_buffer->size() >= n) {
        return handler(outcome::success());
      }

      auto to_read = n - read_buffer->size();
      auto buf = std::make_shared<common::ByteArray>(to_read, 0);
      return connection->read(
          *buf, to_read,
          [self{shared_from_this()}, buf, h = std::move(handler),
           to_read](auto &&res) {
            if (!res) {
              return h(res.error());
            }
            if (boost::asio::buffer_copy(
                    self->read_buffer->prepare(to_read),
                    boost::asio::const_buffer(buf->data(), to_read))
                != to_read) {
              return h(MultiselectError::INTERNAL_ERROR);
            }
            self->read_buffer->commit(to_read);
            h(outcome::success());
          });
    }

    ConnectionState(
        std::shared_ptr<basic::ReadWriter> conn,
        gsl::span<const peer::Protocol> protocols,
        std::function<void(const outcome::result<peer::Protocol> &)> proto_cb,
        std::shared_ptr<common::ByteArray> write_buffer,
        std::shared_ptr<boost::asio::streambuf> read_buffer,
        size_t buffers_index, std::shared_ptr<Multiselect> multiselect,
        NegotiationStatus status = NegotiationStatus::NOTHING_SENT)
        : connection{std::move(conn)},
          protocols{std::make_shared<std::vector<peer::Protocol>>(
              protocols.begin(), protocols.end())},
          left_protocols{
              std::make_shared<std::vector<peer::Protocol>>(*this->protocols)},
          proto_callback{std::move(proto_cb)},
          write_buffer{std::move(write_buffer)},
          read_buffer{std::move(read_buffer)},
          buffers_index{buffers_index},
          multiselect{std::move(multiselect)},
          status{status} {}
  };
}  // namespace libp2p::protocol_muxer

#endif  // LIBP2P_CONNECTION_STATE_HPP


text: #include <boost/asio/local/basic_endpoint.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//  ================================================================
//  Created by Gregory Kramida on 10/23/18.
//  Copyright (c) 2018 Gregory Kramida
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at

//  http://www.apache.org/licenses/LICENSE-2.0

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

//libraries
#include <Eigen/Eigen>
#include <unsupported/Eigen/CXX11/Tensor>

//local
#include "data_term.hpp"

namespace eig = Eigen;

namespace nonrigid_optimization {
namespace slavcheva{

void compute_energy_gradient(const eig::MatrixXf& warped_live_field, const eig::MatrixXf& canonical_field,
                             const eig::MatrixXf& warp_field_x, const eig::MatrixXf& warp_field_y,
                             eig::MatrixXf& gradient_field_x, eig::MatrixXf& gradient_field_y,
                             bool band_union_only = true);

} //namespace slavcheva
}//namespace nonrigid_optimization

max_stars_repo_name: Algomorph/LevelSetFusionExperimentsCPP

max_issues_repo_name: Algomorph/LevelSetFusionExperimentsCPP

max_forks_repo_name: Algomorph/LevelSetFusionExperimentsCPP


text:
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <boost/config.hpp>
#include <vector>
#include <iostream>

#include <stdlib.h>
#include <boost/pending/bucket_sorter.hpp>

template <class Integral>
struct trivial_id {
  std::size_t operator[](Integral i) {
    return i;
  }
  std::size_t operator[](Integral i) const {
    return i;
  }
};

int main() {
  using namespace std;
  using boost::bucket_sorter;

  const std::size_t N = 10;

  vector<std::size_t> bucket(N);
  for (std::size_t i=0; i<N; i++) {
    bucket[i] = rand() % N;
    cout.width(6);
    cout << "Number " << i << " has its bucket "  << bucket[i] << endl;
  }

  typedef trivial_id<int> ID;
  typedef bucket_sorter<std::size_t, int,
    vector<std::size_t>::iterator, ID> BS;
  BS my_bucket_sorter(N, N, bucket.begin());

  for (std::size_t ii=0; ii<N; ii++)
    my_bucket_sorter.push(ii);

  std::size_t j;
  for (j=0; j<N; j++) {
    cout << "The bucket " << j;
    if ( ! my_bucket_sorter[j].empty() ) {
      cout << " has number ";
      do {
        int v = my_bucket_sorter[j].top();
        my_bucket_sorter[j].pop();
        cout << v << " ";
      } while ( ! my_bucket_sorter[j].empty() );
      cout << endl;
    } else {
      cout << " has no number associated with." << endl;
    }
  }

  for (std::size_t k=0; k<N; k++)
    my_bucket_sorter.push(k);

  my_bucket_sorter.remove(5);
  my_bucket_sorter.remove(7);

  cout << "Afer remove number 5 and 7, check correctness again." << endl;

  for (j=0; j<N; j++) {
    cout << "The bucket " << j;
    if ( ! my_bucket_sorter[j].empty() ) {
      cout << " has number ";
      do {
        int v = my_bucket_sorter[j].top();
        my_bucket_sorter[j].pop();
        cout << v << " ";
      } while ( ! my_bucket_sorter[j].empty() );
      cout << endl;
    } else {
      cout << " has no number associated with." << endl;
    }
  }

  std::size_t iii;
  for (iii=0; iii<N; iii++) {
    std::size_t current = rand() % N;
    if ( ! my_bucket_sorter[current].empty() ) {
      int v = my_bucket_sorter[current].top();
      my_bucket_sorter[current].pop();
      bucket[v] = rand() % N;
      my_bucket_sorter.push(v);
    }
  }

  for (iii=0; iii<N; iii++) {
    std::size_t current = rand() % N;
    if ( ! my_bucket_sorter[current].empty() ) {
      int v = my_bucket_sorter[current].top();
      bucket[v] = rand() % N;
      my_bucket_sorter.update(v);
    }
  }

    return 0;
}

ext: cpp


text:
/**
 Boost Logging library

 Author: John Torjo, www.torjo.com

 Copyright (C) 2007 John Torjo (see www.torjo.com for email)

 Distributed under the Boost Software License, Version 1.0.
    (See accompanying file LICENSE_1_0.txt or copy at
          http://www.boost.org/LICENSE_1_0.txt)

 See http://www.boost.org for updates, documentation, and revision history.
 See http://www.torjo.com/log2/ for more details
*/

/**
@example use_tss_ostringstream.cpp

@copydoc use_tss_ostringstream

@page use_tss_ostringstream use_tss_ostringstream.cpp Example

This usage:
- You have one logger
- You have one filter, always turned on
- You want to format the message before it's written
- The logger has several log destinations
    - The output goes to console and debug output window
    - Formatting - prefix each message by its index, and append newline

Optimizations:
- use tss_ostringstream (each thread has its own ostringstream copy, to make writing faster:
  when logging of a message, we won't need to create the ostringstream first ; it's created only once per thread )
- use a cache string (from optimize namespace), in order to make formatting the message faster

In this example, all output will be written to the console and debug window.
It will be:

@code
[1] this is so cool 1
[2] this is so cool again 2
[3] this is too cool 3
@endcode

*/

#include <boost/logging/format_fwd.hpp>

BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )

// FIXME need to set the gather class

#include <boost/logging/format.hpp>

using namespace boost::logging;

typedef logger_format_write< > logger_type;

BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
BOOST_DECLARE_LOG(g_l, logger_type)

#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )

BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
BOOST_DEFINE_LOG(g_l, logger_type)

void use_tss_ostringstream_example() {
    //         add formatters and destinations
    //         That is, how the message is to be formatted and where should it be written to

    g_l()->writer().add_formatter( formatter::idx(), "[%] "  );
    g_l()->writer().add_formatter( formatter::append_newline_if_needed() );
    g_l()->writer().add_destination( destination::cout() );
    g_l()->writer().add_destination( destination::dbg_window() );
    g_l()->mark_as_initialized();

    int i = 1;
    L_ << "this is so cool " << i++;
    L_ << "this is so cool again " << i++;
    L_ << "this is so too cool " << i++;
}

int main() {
    use_tss_ostringstream_example();
}

// End of file

max_stars_repo_name: gbucknell/fsc-sdk

max_issues_repo_name: gbucknell/fsc-sdk

max_forks_repo_name: gbucknell/fsc-sdk


text:
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
//
//  SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef HPX_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_IF_HPP
#define HPX_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_IF_HPP

#include <hpx/config.hpp>

#if !defined(HPX_WINDOWS)
#include <hpx/components/process/util/posix/initializers/initializer_base.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/counting_range.hpp>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#ifndef HPX_PROCESS_POSIX_MAX_FD
#   define HPX_PROCESS_POSIX_MAX_FD 32
#endif

namespace hpx { namespace components { namespace process { namespace posix {

namespace initializers {

template <class Predicate>
class close_fds_if_ : public initializer_base
{
private:
    static void close(int fd)
    {
        ::fcntl(fd, F_SETFD, FD_CLOEXEC);
    }

public:
    explicit close_fds_if_(const Predicate &pred) : pred_(pred) {}

    template <class PosixExecutor>
    void on_exec_setup(PosixExecutor&) const
    {
        boost::for_each(
            boost::adaptors::filter(
                boost::counting_range(0, upper_bound()),
                pred_
            ),
            close
        );
    }

private:
    static int upper_bound()
    {
        int up;
#if defined(F_MAXFD)
        do
        {
            up = ::fcntl(0, F_MAXFD);
        } while (up == -1 && errno == EINTR);
        if (up == -1)
#endif
            up = ::sysconf(_SC_OPEN_MAX);
        if (up == -1)
            up = HPX_PROCESS_POSIX_MAX_FD;
        return up;
    }

    Predicate pred_;
};

template <class Predicate>
close_fds_if_<Predicate> close_fds_if(const Predicate &pred)
{
    return close_fds_if_<Predicate>(pred);
}

}

}}}}

#endif
#endif

max_stars_repo_name: jnvance/hpx

max_issues_repo_name: jnvance/hpx

max_forks_repo_name: jnvance/hpx


text:
// Copyright Takatoshi Kondo 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include "../common/test_main.hpp"
#include "../common/global_fixture.hpp"

#include <set>
#include <algorithm>
#include <random>

#include <boost/format.hpp>

#include <mqtt/broker/retained_topic_map.hpp>

BOOST_AUTO_TEST_SUITE(ut_retained_map)

BOOST_AUTO_TEST_CASE(general) {
    MQTT_NS::broker::retained_topic_map<std::string> map;
    map.insert_or_assign("a/b/c", "123");
    BOOST_TEST(map.size() == 1);
    BOOST_TEST(map.internal_size() == 4);

    BOOST_TEST(map.insert_or_assign("a/b", "123") == 1);
    BOOST_TEST(map.size() == 2);
    BOOST_TEST(map.internal_size() == 4);

    BOOST_TEST(map.insert_or_assign("a/b", "123") == 0);
    BOOST_TEST(map.size() == 2);
    BOOST_TEST(map.internal_size() == 4);

    BOOST_TEST(map.erase("a") == 0);
    BOOST_TEST(map.erase("a") == 0);

    BOOST_TEST(map.erase("a/b/c") == 1);
    BOOST_TEST(map.size() == 1);

    BOOST_TEST(map.erase("a/b") == 1);
    BOOST_TEST(map.size() == 0);
    BOOST_TEST(map.internal_size() == 1);

    std::vector<std::string> values = {
        "example/test/A", "example/test/B", "example/A/test", "example/B/test"
    };

    for (auto const& i : values) {
        map.insert_or_assign(i, i);
    }
    BOOST_TEST(map.size() == 4);

    std::vector<std::string> matches;
    map.find(values[0], [&matches](std::string const &a) {
        matches.push_back(a);
    });
    BOOST_TEST(matches.size() == 1);
    BOOST_TEST(matches[0] == values[0]);

    matches = { };
    map.find(values[1], [&matches](std::string const &a) {
        matches.push_back(a);
    });
    BOOST_TEST(matches.size() == 1);
    BOOST_TEST(matches[0] == values[1]);

    matches = { };
    map.find("example/test/+", [&matches](std::string const &a) {
        matches.push_back(a);
    });
    BOOST_TEST(matches.size() == 2);
    BOOST_TEST(matches[0] == values[0]);
    BOOST_TEST(matches[1] == values[1]);

    matches = { };
    map.find("example/+/B", [&matches](std::string const &a) {
        matches.push_back(a);
    });
    BOOST_TEST(matches.size() == 1);
    BOOST_TEST(matches[0] == values[1]);

    matches = { };
    map.find("example/#", [&matches](std::string const &a) {
        matches.push_back(a);
    });

    BOOST_TEST(matches.size() == 4);

    matches = { };
    map.find("#", [&matches](std::string const &a) {
        matches.push_back(a);
    });

    BOOST_TEST(matches.size() == 4);

    std::vector<std::string> diff;
    std::sort(matches.begin(), matches.end());
    std::sort(values.begin(), values.end());
    std::set_difference(matches.begin(), matches.end(), values.begin(), values.end(), diff.begin());
    BOOST_TEST(diff.empty());

    BOOST_TEST(map.erase("non-existent") == 0);

    for (auto const& i : values) {
        BOOST_TEST(map.size() != 0);
        BOOST_TEST(map.erase(i) == 1);
    }

    BOOST_TEST(map.size() == 0);
    BOOST_TEST(map.internal_size() == 1);
}

BOOST_AUTO_TEST_CASE(erase_lower_first) {
    MQTT_NS::broker::retained_topic_map<std::string> map;
    map.insert_or_assign("a/b/c", "1");
    map.insert_or_assign("a/b", "2");

    auto e1 = map.erase("a/b/c"); // erase lower first
    BOOST_TEST(e1 == 1);
    {
        std::set<std::string> match {
            "2",
        };
        map.find(
            "a/b",
            [&](std::string const &v) {
                BOOST_TEST(match.erase(v) == 1);
            }
        );
        BOOST_TEST(match.empty());
    }
    {
        map.find(
            "a/b/c",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }

    auto e2 = map.erase("a/b");
    BOOST_TEST(e2 == 1);
    {
        map.find(
            "a/b/c",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }
    {
        map.find(
            "a/b",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }
}

BOOST_AUTO_TEST_CASE(erase_upper_first) {
    MQTT_NS::broker::retained_topic_map<std::string> map;
    map.insert_or_assign("a/b/c", "1");
    map.insert_or_assign("a/b", "2");

    auto e1 = map.erase("a/b"); // erase upper first

    BOOST_TEST(e1 == 1);
    {
        std::set<std::string> match {
            "1",
        };
        map.find(
            "a/b/c",
            [&](std::string const &v) {
                BOOST_TEST(match.erase(v) == 1);
            }
        );
        BOOST_TEST(match.empty());
    }
    {
        map.find(
            "a/b",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }

    auto e2 = map.erase("a/b/c");
    BOOST_TEST(e2 == 1);
    {
        map.find(
            "a/b/c",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }
    {
        map.find(
            "a/b",
            [&](std::string const &) {
                BOOST_TEST(false);
            }
        );
    }
}

BOOST_AUTO_TEST_CASE(large_number_of_topics) {
    MQTT_NS::broker::retained_topic_map<std::pair<std::size_t, std::size_t>> map;

    std::vector< std::pair<std::string, std::pair<std::size_t, std::size_t> > > created_topics;

    constexpr std::size_t num_topics = 25;
    for (std::size_t i = 0; i < num_topics; ++i) {
        for (std::size_t j = 0; j < num_topics; ++j) {
            std::string topic = (boost::format("topic/first_level_%d/second_level_%d") % i % j).str();
            auto value = std::make_pair(i, j);

            map.insert_or_assign(topic, value);

            created_topics.push_back(std::make_pair(topic, value));
        }
    }

    BOOST_TEST(map.size() == num_topics * num_topics);

    std::vector< std::pair<std::size_t, std::size_t> > received_values;
    std::vector< std::pair<std::size_t, std::size_t> > searched_values;

    std::shuffle(created_topics.begin(), created_topics.end(), std::default_random_engine(0x12345));

    for (auto const& i : created_topics) {
       map.find(
            i.first,
            [&](std::pair<std::size_t, std::size_t> const& value) {
                received_values.push_back(value);
            }
        );

        searched_values.push_back(i.second);
    }

    BOOST_TEST(searched_values == received_values);

    for (auto const& i : created_topics) {
        map.erase(i.first);
    }

    BOOST_TEST(map.size() == 0);
    BOOST_TEST(map.internal_size() == 1);
}

BOOST_AUTO_TEST_SUITE_END()


text:
/*    Copyright (c) 2010-2019, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 *
 *    References
 *      Introduction to Flight, Fifth edition, Appendix A, John D. Anderson Jr., McGraw Hill, 2005.
 *      US Standard Atmosphere 1976,
 *          http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770009539_1977009539.pdf.
 *      Forget, François, et al. "Improved general circulation models of the Martian atmosphere from the surface to above 80 km."
 *          Journal of Geophysical Research: Planets 104.E10 (1999): 24155-24175.
 *      Millour, E., et al. "The Mars Climate Database (MCD version 5.2)." European Planetary Science Congress 2015. Vol. 10. EPSC, 2015.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN

#include <limits>

#include <boost/test/unit_test.hpp>

#include "tudat/astro/basic_astro/unitConversions.h"
#include "tudat/astro/aerodynamics/tabulatedAtmosphere.h"
#include "tudat/io/basicInputOutput.h"

namespace tudat
{
namespace unit_tests
{

BOOST_AUTO_TEST_SUITE( test_tabulated_atmosphere )

// Summary of tests.
// Test 1: Test tabulated atmosphere at sea level.
// Test 2: Test tabulated atmosphere at 10.0 km altitude including passing arbitrary longitude
//         and latitude.
// Test 3: Test tabulated atmosphere at 10.05 km altitude when just passing the altitude.
// Test 4: Test tabulated atmosphere at 1000 km altitude with table.
// Test 5: Test if the atmosphere file can be read multiple times.
// Test 6: Test if the position-independent functions work.

//! Check if the atmosphere is calculated correctly at sea level.
// Values from (US Standard Atmosphere, 1976).
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereAtSeaLevel )
{
    // Create a tabulated atmosphere object.
    std::string tabulatedAtmosphereFile = paths::getAtmosphereTablesPath( ) +
            "/USSA1976Until100kmPer100mUntil1000kmPer1000m.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFile );

    // Declare tolerance used for Boost tests.
    const double tolerance = std::numeric_limits< double >::epsilon( );

    const double altitude = 0.0;
    BOOST_CHECK_CLOSE_FRACTION( 1.225, tabulatedAtmosphere.getDensity( altitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 101325.0, tabulatedAtmosphere.getPressure( altitude ), 1.0e-4 );
    BOOST_CHECK_CLOSE_FRACTION( 288.15, tabulatedAtmosphere.getTemperature( altitude ), tolerance );
}

//! Test tabulated atmosphere at 10km altitude including passing arbitrary longitude and latitude.
// The given value for pressure was obtained from table in book.
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereAt10km )
{
    // Create a tabulated atmosphere object.
    std::string tabulatedAtmosphereFile = paths::getAtmosphereTablesPath( ) +
            "/USSA1976Until100kmPer100mUntil1000kmPer1000m.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFile );
    const double altitude = 10.0e3;
    const double longitude = 0.0;
    const double latitude = 0.0;
    const double time = 0.0;

    BOOST_CHECK_SMALL( 0.41351 - tabulatedAtmosphere.getDensity( altitude,  longitude, latitude, time ), 1.0e-4 );
    BOOST_CHECK_SMALL( 26500.0 - tabulatedAtmosphere.getPressure( altitude,  longitude, latitude, time ), 1.0 );
    BOOST_CHECK_SMALL( 223.26 - tabulatedAtmosphere.getTemperature( altitude,  longitude, latitude, time ), 1.0e-2 );
}

//! Test tabulated atmosphere at 10.05 km altitude when just passing the altitude.
// Check whether the atmosphere is calculated correctly at 10.05 km.
// The values are linear interpolated values based on book values.
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereAt10p5km )
{
    // Create a tabulated atmosphere object.
    std::string tabulatedAtmosphereFile = paths::getAtmosphereTablesPath( ) +
            "/USSA1976Until100kmPer100mUntil1000kmPer1000m.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFile );
    const double altitude = 10.05e3;

    BOOST_CHECK_SMALL( 0.4110 - tabulatedAtmosphere.getDensity( altitude ), 1.0e-3 );
    BOOST_CHECK_SMALL( 26299.0 - tabulatedAtmosphere.getPressure( altitude ), 1.0 );
    BOOST_CHECK_SMALL( 222.9350 - tabulatedAtmosphere.getTemperature( altitude ), 2.0e-2 );
}

//! Test tabulated atmosphere at 1000 km altitude.
// Check whether the atmosphere is calculated correctly at 1000 km. Compared with the input table.
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereAt1000kmtab )
{
    // Create a tabulated atmosphere object.
    std::string tabulatedAtmosphereFiles = paths::getAtmosphereTablesPath( ) +
            "/USSA1976Until100kmPer100mUntil1000kmPer1000m.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles );
    const double altitude = 1.0e6;

    // Declare tolerance used for Boost tests.
    const double tolerance = std::numeric_limits< double >::epsilon( );

    BOOST_CHECK_CLOSE_FRACTION( 3.5618e-15, tabulatedAtmosphere.getDensity( altitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 7.5158e-9, tabulatedAtmosphere.getPressure( altitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1000.0, tabulatedAtmosphere.getTemperature( altitude ), tolerance );
}

//! Check if the atmosphere is calculated correctly when the variables are shuffled
// Values from (US Standard Atmosphere, 1976).
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereDependentVariables )
{
    // Create vector of dependent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables;
    dependentVariables.push_back( aerodynamics::pressure_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::density_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::temperature_dependent_atmosphere );

    // Create a tabulated atmosphere object.
    std::string tabulatedAtmosphereFile = paths::getAtmosphereTablesPath( ) +
            "/USSA1976Until100kmPer100mUntil1000kmPer1000m.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFile, dependentVariables );

    // Declare tolerance used for Boost tests.
    const double tolerance = std::numeric_limits< double >::epsilon( );

    const double altitude = 0.0;
    // Pressure and Density are switched
    BOOST_CHECK_CLOSE_FRACTION( 101325.0, tabulatedAtmosphere.getDensity( altitude ), 1.0e-4 );
    BOOST_CHECK_CLOSE_FRACTION( 1.225, tabulatedAtmosphere.getPressure( altitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 288.15, tabulatedAtmosphere.getTemperature( altitude ), tolerance );
}

//! Check if the atmosphere is calculated correctly when all the possible dependent variables are used and shuffled
// Values from Mars Climate Database Web Interface (http://www-mars.lmd.jussieu.fr/mcd_python/), avaraged over time, latitude and longitude.
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereAllDependentVariables )
{
    // Create vector of dependent and independent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables;
    dependentVariables.push_back( aerodynamics::pressure_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::molar_mass_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::specific_heat_ratio_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::gas_constant_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::temperature_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::density_dependent_atmosphere );
    std::vector< aerodynamics::AtmosphereIndependentVariables > independentVariables = { aerodynamics::latitude_dependent_atmosphere };

    // Create a tabulated atmosphere object.
    std::map< int, std::string > tabulatedAtmosphereFiles;
    tabulatedAtmosphereFiles[ 0 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphere.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles, independentVariables, dependentVariables );

    // Declare tolerance used for Boost tests.
    const double tolerance = std::numeric_limits< double >::epsilon( );

    const double latitude = 5e4;
    BOOST_CHECK_CLOSE_FRACTION( 4.3604106892e-02, tabulatedAtmosphere.getDensity( 0.0, 0.0, latitude ), 1.0e-4 );
    BOOST_CHECK_CLOSE_FRACTION( 7.6178752157e-05, tabulatedAtmosphere.getPressure( 0.0, 0.0, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.3794210386e+00, tabulatedAtmosphere.getTemperature( 0.0, 0.0, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.9068065814e+02, tabulatedAtmosphere.getSpecificGasConstant( 0.0, 0.0, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.6104994141e+02, tabulatedAtmosphere.getRatioOfSpecificHeats( 0.0, 0.0, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 2.3477457225e+00, tabulatedAtmosphere.getMolarMass( 0.0, 0.0, latitude ), 1.0e-4 );
    BOOST_CHECK_CLOSE_FRACTION( 205.817372408135, tabulatedAtmosphere.getSpeedOfSound( 0.0, 0.0, latitude ), 10.0 * tolerance );
}

//! Check if the atmosphere is calculated correctly when more than one independent variable is used, and when
//! dependent variables are shuffled.
// Values from Mars Climate Database Web Interface (http://www-mars.lmd.jussieu.fr/mcd_python/), avaraged over time.
BOOST_AUTO_TEST_CASE( testMultiDimensionalTabulatedAtmosphere )
{
    // Create vector of dependent and independent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables = {
        aerodynamics::density_dependent_atmosphere, aerodynamics::pressure_dependent_atmosphere,
        aerodynamics::temperature_dependent_atmosphere};
    std::vector< aerodynamics::AtmosphereIndependentVariables > independentVariables = {
        aerodynamics::longitude_dependent_atmosphere, aerodynamics::latitude_dependent_atmosphere,
        aerodynamics::altitude_dependent_atmosphere };

    // Create a tabulated atmosphere object.
    std::map< int, std::string > tabulatedAtmosphereFiles;
    tabulatedAtmosphereFiles[ 0 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/density.dat";
    tabulatedAtmosphereFiles[ 1 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/pressure.dat";
    tabulatedAtmosphereFiles[ 2 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/temperature.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles, independentVariables, dependentVariables );

    // Declare tolerance used for Boost tests.
    const double tolerance = 1e-7;

    // Define independent variable conditions
    const double altitude = 5.0e4;
    const double longitude = unit_conversions::convertDegreesToRadians( -180.0 );
    const double latitude = unit_conversions::convertDegreesToRadians( -90.0 );

    // Check that values matches with MATLAB interpolation (note that dependent variables are shuffled)
    BOOST_CHECK_CLOSE_FRACTION( 5.2805275e-05, tabulatedAtmosphere.getDensity( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.6627685, tabulatedAtmosphere.getPressure( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 151.544, tabulatedAtmosphere.getTemperature( altitude, longitude, latitude ), 1e2 * tolerance );
}

//! Check if the atmosphere is calculated correctly when more than one independent variable is used, and when both independent
//! and dependent variables are shuffled. Also tests for linear interpolation.
// Values from Mars Climate Database Web Interface (http://www-mars.lmd.jussieu.fr/mcd_python/), avaraged over time.
BOOST_AUTO_TEST_CASE( testMultiDimensionalTabulatedAtmosphereWithInterpolationAndShuffledVariables )
{
    // Create vector of dependent and independent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables = {
        aerodynamics::specific_heat_ratio_dependent_atmosphere, aerodynamics::temperature_dependent_atmosphere,
        aerodynamics::density_dependent_atmosphere, aerodynamics::pressure_dependent_atmosphere,
        aerodynamics::gas_constant_dependent_atmosphere };
    std::vector< aerodynamics::AtmosphereIndependentVariables > independentVariables = {
        aerodynamics::longitude_dependent_atmosphere, aerodynamics::latitude_dependent_atmosphere,
        aerodynamics::altitude_dependent_atmosphere };

    // Create a tabulated atmosphere object.
    std::map< int, std::string > tabulatedAtmosphereFiles;
    tabulatedAtmosphereFiles[ 0 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/specificHeatRatio.dat";
    tabulatedAtmosphereFiles[ 1 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/temperature.dat";
    tabulatedAtmosphereFiles[ 2 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/density.dat";
    tabulatedAtmosphereFiles[ 3 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/pressure.dat";
    tabulatedAtmosphereFiles[ 4 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/gasConstant.dat";
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles, independentVariables, dependentVariables );

    // Declare tolerance used for Boost tests.
    const double tolerance = 1e-5;

    // Define independent variable conditions
    const double altitude = 236.9862e3;
    const double longitude = unit_conversions::convertDegreesToRadians( 72.98632 );
    const double latitude = unit_conversions::convertDegreesToRadians( -65.9762 );

    // Check that values matches with MATLAB interpolation (note that dependent variables are shuffled)
    BOOST_CHECK_CLOSE_FRACTION( 5.50924276619674e-13, tabulatedAtmosphere.getDensity( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 5.05433422347663e-08, tabulatedAtmosphere.getPressure( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 174.841221295332, tabulatedAtmosphere.getTemperature( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 536.101455389577, tabulatedAtmosphere.getSpecificGasConstant( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.66646490380313, tabulatedAtmosphere.getRatioOfSpecificHeats( altitude, longitude, latitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 395.224168752852, tabulatedAtmosphere.getSpeedOfSound( altitude, longitude, latitude ), tolerance );
}

//! Check if the atmosphere is calculated correctly when default extrapolation values are used.
// Values from Mars Climate Database Web Interface (http://www-mars.lmd.jussieu.fr/mcd_python/), avaraged over time.
BOOST_AUTO_TEST_CASE( testMultiDimensionalTabulatedAtmosphereDefaultExtrapolation )
{
    // Create vector of dependent and independent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables = {
        aerodynamics::pressure_dependent_atmosphere, aerodynamics::temperature_dependent_atmosphere,
        aerodynamics::specific_heat_ratio_dependent_atmosphere, aerodynamics::density_dependent_atmosphere };
    std::vector< aerodynamics::AtmosphereIndependentVariables > independentVariables = {
        aerodynamics::longitude_dependent_atmosphere, aerodynamics::latitude_dependent_atmosphere,
        aerodynamics::altitude_dependent_atmosphere };

    // Create a tabulated atmosphere object.
    std::map< int, std::string > tabulatedAtmosphereFiles;
    tabulatedAtmosphereFiles[ 0 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/pressure.dat";
    tabulatedAtmosphereFiles[ 1 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/temperature.dat";
    tabulatedAtmosphereFiles[ 2 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/specificHeatRatio.dat";
    tabulatedAtmosphereFiles[ 3 ] = paths::getAtmosphereTablesPath( ) + "/MCDMeanAtmosphereTimeAverage/density.dat";

    // Test 1: check with single vector of default values
    {
        std::vector< interpolators::BoundaryInterpolationType > boundaryHandling = { interpolators::throw_exception_at_boundary,
                                                                                interpolators::use_boundary_value_with_warning,
                                                                                interpolators::use_default_value_with_warning };
        std::vector< double > defualtExtrapolationValues = { 100, 250, 1.3, 0 };
        aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles, independentVariables, dependentVariables,
                                                               boundaryHandling, defualtExtrapolationValues );

        // Declare tolerance used for Boost tests.
        const double tolerance = 1e-7;

        // Define independent variable conditions
        const std::vector< double > longitude = { unit_conversions::convertDegreesToRadians( 0.0 ),
                                                  unit_conversions::convertDegreesToRadians( 0.0 ) + 10.0,
                                                  unit_conversions::convertDegreesToRadians( 0.0 ) };
        const std::vector< double > latitude = { unit_conversions::convertDegreesToRadians( 0.0 ),
                                                 unit_conversions::convertDegreesToRadians( 0.0 ),
                                                 unit_conversions::convertDegreesToRadians( 0.0 ) + 10.0 };
        const std::vector< double > altitude = { 5.0e7, 5.0e4, 5.0e4 };

        // Expected results
        std::vector< double > boundaryValues = { 0.877653865782941, 163.354129386099, 1.37774305607899, 2.82975546661156e-05 };
        const std::vector< bool > expectedException = { false, true, false };
        std::vector< double > expectedResult;
        bool exception;

        // Check that values matches with MATLAB interpolation (note that dependent variables are shuffled)
        for ( unsigned int i = 0; i < 3; i++ )
        {
            exception = false;
            expectedResult = ( i == 0 ) ? defualtExtrapolationValues : boundaryValues;
            try
            {
                BOOST_CHECK_CLOSE_FRACTION( expectedResult.at( 0 ),
                                            tabulatedAtmosphere.getPressure( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                            tolerance );
                BOOST_CHECK_CLOSE_FRACTION( expectedResult.at( 1 ),
                                            tabulatedAtmosphere.getTemperature( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                            tolerance );
                BOOST_CHECK_CLOSE_FRACTION( expectedResult.at( 2 ),
                                            tabulatedAtmosphere.getRatioOfSpecificHeats( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                            tolerance );
                BOOST_CHECK_CLOSE_FRACTION( expectedResult.at( 3 ),
                                            tabulatedAtmosphere.getDensity( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                            tolerance );
            }
            catch( std::runtime_error const& )

            {
                exception = true;
            }
            BOOST_CHECK_EQUAL( exception, expectedException.at( i ) );
        }
    }

    // Test 2: check with full set of default values
    {
        std::vector< interpolators::BoundaryInterpolationType > boundaryHandling =
        std::vector< interpolators::BoundaryInterpolationType >( independentVariables.size( ), interpolators::use_default_value );
        std::vector< std::vector< std::pair< double, double > > > defualtExtrapolationValues =
        {
            std::vector< std::pair< double, double > >( independentVariables.size( ), std::make_pair( -100.0, 100.0 ) ),
            std::vector< std::pair< double, double > >( independentVariables.size( ), std::make_pair( 250.0, 0.08652 ) ),
            std::vector< std::pair< double, double > >( independentVariables.size( ), std::make_pair( 1.4, 1.3 ) ),
            std::vector< std::pair< double, double > >( independentVariables.size( ), std::make_pair( 1e-3, 0.0 ) )
        };
        aerodynamics::TabulatedAtmosphere tabulatedAtmosphere( tabulatedAtmosphereFiles, independentVariables, dependentVariables,
                                                               boundaryHandling, defualtExtrapolationValues );

        // Declare tolerance used for Boost tests.
        const double tolerance = 1e-7;

        // Define independent variable conditions
        const std::vector< double > longitude = { unit_conversions::convertDegreesToRadians( 0.0 ) - 10.0,
                                                  unit_conversions::convertDegreesToRadians( 0.0 ) + 10.0,
                                                  unit_conversions::convertDegreesToRadians( 0.0 ),
                                                  unit_conversions::convertDegreesToRadians( 0.0 ),
                                                  unit_conversions::convertDegreesToRadians( 0.0 ),
                                                  unit_conversions::convertDegreesToRadians( 0.0 ) };
        const std::vector< double > latitude = { unit_conversions::convertDegreesToRadians( 0.0 ),
                                                 unit_conversions::convertDegreesToRadians( 0.0 ),
                                                 unit_conversions::convertDegreesToRadians( 0.0 ) - 10.0,
                                                 unit_conversions::convertDegreesToRadians( 0.0 ) + 10.0,
                                                 unit_conversions::convertDegreesToRadians( 0.0 ),
                                                 unit_conversions::convertDegreesToRadians( 0.0 ) };
        const std::vector< double > altitude = { 5.0e5, 5.0e5, 5.0e5, 5.0e5, 0.0, 5.0e10 };

        // Check that values matches default values
        for ( unsigned int i = 0; i < altitude.size( ); i++ )
        {
            std::vector< double > expectedValue;
            for ( unsigned int j = 0; j < dependentVariables.size( ); j++ )
            {
                if ( ( i % 2 ) == 0.0 )
                {
                    expectedValue.push_back( defualtExtrapolationValues.at( j ).at( std::floor( i / 2.0 ) ).first );
                }
                else
                {
                    expectedValue.push_back( defualtExtrapolationValues.at( j ).at( std::floor( i / 2.0 ) ).second );
                }
            }

            BOOST_CHECK_CLOSE_FRACTION( expectedValue.at( 0 ),
                                        tabulatedAtmosphere.getPressure( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                        tolerance );
            BOOST_CHECK_CLOSE_FRACTION( expectedValue.at( 1 ),
                                        tabulatedAtmosphere.getTemperature( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                        tolerance );
            BOOST_CHECK_CLOSE_FRACTION( expectedValue.at( 2 ),
                                        tabulatedAtmosphere.getRatioOfSpecificHeats( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                        tolerance );
            BOOST_CHECK_CLOSE_FRACTION( expectedValue.at( 3 ),
                                        tabulatedAtmosphere.getDensity( altitude.at( i ), longitude.at( i ), latitude.at( i ) ),
                                        tolerance );
        }
    }
}

//! Check if the atmosphere is calculated correctly when heat ratio and gas constants are added.
// Values from (US Standard Atmosphere, 1976).
BOOST_AUTO_TEST_CASE( testTabulatedAtmosphereExtraVariables )
{
    // Create vector of dependent variables
    std::vector< aerodynamics::AtmosphereDependentVariables > dependentVariables;
    dependentVariables.push_back( aerodynamics::density_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::pressure_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::temperature_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::specific_heat_ratio_dependent_atmosphere );
    dependentVariables.push_back( aerodynamics::gas_constant_dependent_atmosphere );

    // Create a tabulated atmosphere object.
    aerodynamics::TabulatedAtmosphere tabulatedAtmosphere(
                paths::getAtmosphereTablesPath( ) + "/USSA1976Until100kmPer100mUntil1000kmPer1000m_wHR_GC.dat",
                dependentVariables );

    // Declare tolerance used for Boost tests.
    const double tolerance = std::numeric_limits< double >::epsilon( );

    const double altitude = 0.0;
    BOOST_CHECK_CLOSE_FRACTION( 8.0, tabulatedAtmosphere.getSpecificGasConstant( altitude ), tolerance );
    BOOST_CHECK_CLOSE_FRACTION( 1.7, tabulatedAtmosphere.getRatioOfSpecificHeats( altitude ), 1.0e-4 );
}

BOOST_AUTO_TEST_SUITE_END( )

} // namespace unit_tests
} // namespace tudat


text:
/*
 * Copyright 2022 HEAVY.AI, 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.
 */

/*
 * @file ExpressionParser.cpp
 * @brief General Expression Parser using muparserx
 *
 */

#include "ImportExport/ExpressionParser.h"

#include <regex>

#if defined(_MSC_VER)
#include <codecvt>
#include <locale>
#endif

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>

#include <muparserx/mpParser.h>

#include "Logger/Logger.h"
#include "Shared/StringTransform.h"

namespace import_export {

namespace {

std::string ms_to_ss(const mup::string_type& s) {
#if defined(_MSC_VER)
  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
  return converter.to_bytes(s);
#else
  return s;
#endif
}

mup::string_type ss_to_ms(const std::string& s) {
#if defined(_MSC_VER)
  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
  return converter.from_bytes(s);
#else
  return s;
#endif
}

#define VALIDATE_ARG_TYPE(arg, t2)    \
  if (args[arg]->GetType() != t2) {   \
    mup::ErrorContext err;            \
    err.Errc = mup::ecINVALID_TYPE;   \
    err.Type1 = args[arg]->GetType(); \
    err.Type2 = t2;                   \
    err.Ident = GetIdent();           \
    throw mup::ParserError(err);      \
  }

#define THROW_INVALID_PARAMETER(arg, what)                                  \
  mup::ErrorContext err;                                                    \
  err.Errc = mup::ecINVALID_PARAMETER;                                      \
  err.Arg = arg;                                                            \
  err.Ident = GetIdent() + ss_to_ms(" (") + ss_to_ms(what) + ss_to_ms(")"); \
  throw mup::ParserError(err);

#define THROW_INVALID_PARAMETER_COUNT()           \
  mup::ErrorContext err;                          \
  err.Errc = mup::ecINVALID_NUMBER_OF_PARAMETERS; \
  err.Ident = GetIdent();                         \
  throw mup::ParserError(err);

class Function_substr : public mup::ICallback {
 public:
  Function_substr() : mup::ICallback(mup::cmFUNC, _T("substr"), -1) {}
  const mup::char_type* GetDesc() const final {
    return _T("return a substring of a string");
  };
  mup::IToken* Clone() const final { return new Function_substr(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    if (argc < 2 || argc > 3) {
      THROW_INVALID_PARAMETER_COUNT();
    }
    VALIDATE_ARG_TYPE(0, 's');
    VALIDATE_ARG_TYPE(1, 'i');
    if (argc == 3) {
      VALIDATE_ARG_TYPE(2, 'i');
    }
    auto const text = args[0]->GetString();
    auto const start = args[1]->GetInteger();
    if (start < 1) {
      THROW_INVALID_PARAMETER(1, "bad 'start'");
    }
    if (argc == 2) {
      if (start > static_cast<int>(text.length())) {
        THROW_INVALID_PARAMETER(1, "bad 'start'");
      }
      *ret = text.substr(start - 1, std::string::npos);
    } else {
      auto const count = args[2]->GetInteger();
      if (count < 1) {
        THROW_INVALID_PARAMETER(2, "bad 'count'");
      } else if ((start - 1) + count > static_cast<int>(text.length())) {
        THROW_INVALID_PARAMETER(2, "bad 'start'/'count'");
      }
      *ret = text.substr(start - 1, count);
    }
  }
};

class Function_regex_match : public mup::ICallback {
 public:
  Function_regex_match() : mup::ICallback(mup::cmFUNC, _T("regex_match"), 2) {}
  const mup::char_type* GetDesc() const final {
    return _T("return a regex-matched section of a string");
  };
  mup::IToken* Clone() const final { return new Function_regex_match(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 2);
    VALIDATE_ARG_TYPE(0, 's');
    VALIDATE_ARG_TYPE(1, 's');
    auto const text = ms_to_ss(args[0]->GetString());
    auto const pattern = ms_to_ss(args[1]->GetString());
    try {
      std::regex regex(pattern, std::regex_constants::extended);
      std::smatch match;
      std::regex_match(text, match, regex);
      if (match.size() != 2u) {
        throw std::runtime_error("must have exactly one match");
      }
      *ret = ss_to_ms(match[1]);
    } catch (std::runtime_error& e) {
      THROW_INVALID_PARAMETER(2, e.what());
    }
  }
};

class Function_split_part : public mup::ICallback {
 public:
  Function_split_part() : mup::ICallback(mup::cmFUNC, _T("split_part"), 3) {}
  const mup::char_type* GetDesc() const final {
    return _T("split a string by a given separator, then return the nth token");
  };
  mup::IToken* Clone() const final { return new Function_split_part(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 3);
    VALIDATE_ARG_TYPE(0, 's');
    VALIDATE_ARG_TYPE(1, 's');
    VALIDATE_ARG_TYPE(2, 'i');
    auto const text = ms_to_ss(args[0]->GetString());
    auto const delimiter = ms_to_ss(args[1]->GetString());
    auto n = args[2]->GetInteger();
    try {
      std::vector<std::string> tokens;
      // split on exact delimiter (cannot use boost::split)
      size_t start{0u}, end{0u};
      while (end != std::string::npos) {
        end = text.find(delimiter, start);
        tokens.push_back(text.substr(start, end - start));
        start = end + delimiter.length();
      }
      if (tokens.size() == 0u) {
        throw std::runtime_error("failed to split");
      }
      int index{0};
      if (n < 0) {
        // reverse index (-1 = last token)
        index = static_cast<int>(tokens.size()) + n;
      } else {
        // forward index (1 = first token)
        index = n - 1;
      }
      if (index < 0 || index >= static_cast<int>(tokens.size())) {
        throw std::runtime_error("bad token index");
      }
      *ret = ss_to_ms(tokens[index]);
    } catch (std::runtime_error& e) {
      THROW_INVALID_PARAMETER(1, e.what());
    }
  }
};

class Function_int : public mup::ICallback {
 public:
  Function_int() : mup::ICallback(mup::cmFUNC, _T("int"), 1) {}
  const mup::char_type* GetDesc() const final { return _T("cast a value to an int"); };
  mup::IToken* Clone() const final { return new Function_int(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    switch (args[0]->GetType()) {
      case 'i':
        *ret = args[0]->GetInteger();
        break;
      case 'f':
        *ret = static_cast<mup::int_type>(args[0]->GetFloat());
        break;
      case 's':
        *ret = static_cast<mup::int_type>(std::stoll(ms_to_ss(args[0]->GetString())));
        break;
      case 'b':
        *ret = args[0]->GetBool() ? static_cast<mup::int_type>(1)
                                  : static_cast<mup::int_type>(0);
        break;
      default: {
        THROW_INVALID_PARAMETER(0, "unsupported type");
      }
    }
  }
};

class Function_float : public mup::ICallback {
 public:
  Function_float() : mup::ICallback(mup::cmFUNC, _T("float"), 1) {}
  const mup::char_type* GetDesc() const final { return _T("cast a value to a float"); };
  mup::IToken* Clone() const final { return new Function_float(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    switch (args[0]->GetType()) {
      case 'i':
        *ret = static_cast<mup::float_type>(args[0]->GetInteger());
        break;
      case 'f':
        *ret = args[0]->GetFloat();
        break;
      case 's':
        *ret = static_cast<mup::float_type>(std::stod(ms_to_ss(args[0]->GetString())));
        break;
      default: {
        THROW_INVALID_PARAMETER(0, "unsupported type");
      }
    }
  }
};

class Function_double : public mup::ICallback {
 public:
  Function_double() : mup::ICallback(mup::cmFUNC, _T("double"), 1) {}
  const mup::char_type* GetDesc() const final { return _T("cast a value to a double"); };
  mup::IToken* Clone() const final { return new Function_double(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    switch (args[0]->GetType()) {
      case 'i':
        *ret = static_cast<mup::float_type>(args[0]->GetInteger());
        break;
      case 'f':
        *ret = args[0]->GetFloat();
        break;
      case 's':
        *ret = static_cast<mup::float_type>(std::stod(ms_to_ss(args[0]->GetString())));
        break;
      default: {
        THROW_INVALID_PARAMETER(0, "unsupported type");
      }
    }
  }
};

class Function_str : public mup::ICallback {
 public:
  Function_str() : mup::ICallback(mup::cmFUNC, _T("str"), 1) {}
  const mup::char_type* GetDesc() const final { return _T("cast a value to a string"); };
  mup::IToken* Clone() const final { return new Function_str(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    switch (args[0]->GetType()) {
      case 'i':
      case 'f':
        *ret = args[0]->ToString();
        break;
      case 's':
        *ret = args[0]->GetString();
        break;
      case 'b':
        *ret = args[0]->GetBool() ? ss_to_ms("true") : ss_to_ms("false");
        break;
      default: {
        THROW_INVALID_PARAMETER(0, "unsupported type");
      }
    }
  }
};

class Function_bool : public mup::ICallback {
 public:
  Function_bool() : mup::ICallback(mup::cmFUNC, _T("bool"), 1) {}
  const mup::char_type* GetDesc() const final { return _T("cast a value to a boolean"); };
  mup::IToken* Clone() const final { return new Function_bool(*this); };
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    switch (args[0]->GetType()) {
      case 'i':
        *ret = args[0]->GetInteger() != 0;
        break;
      case 's': {
        auto const s = strip(to_lower(ms_to_ss(args[0]->GetString())));
        if (s == "true" || s == "t" || s == "1") {
          *ret = true;
        } else if (s == "false" || s == "f" || s == "0") {
          *ret = false;
        } else {
          THROW_INVALID_PARAMETER(0, s.c_str());
        }
      } break;
      case 'b':
        *ret = args[0]->GetBool();
        break;
      default: {
        THROW_INVALID_PARAMETER(0, "unsupported type");
      }
    }
  }
};

class Operator_not : public mup::IOprtInfix {
 public:
  Operator_not() : mup::IOprtInfix(_T("not"), mup::prINFIX) {}
  const mup::char_type* GetDesc() const final { return _T("bool inversion operator"); }
  mup::IToken* Clone() const final { return new Operator_not(*this); }
  void Eval(mup::ptr_val_type& ret, const mup::ptr_val_type* args, int argc) final {
    CHECK_EQ(argc, 1);
    VALIDATE_ARG_TYPE(0, 'b');
    *ret = !(args[0]->GetBool());
  }
};

mup::Value evaluate(mup::ParserX* parser) {
  mup::Value result;
  try {
    result = parser->Eval();
  } catch (mup::ParserError& err) {
    throw std::runtime_error("Parser Error: " + ms_to_ss(err.GetMsg()));
  } catch (std::exception& err) {
    throw std::runtime_error("Unexpected muparserx Error: " + std::string(err.what()));
  }
  return result;
}

}  // namespace

void ExpressionParser::ParserDeleter::operator()(mup::ParserX* parser) {
  delete parser;
}

ExpressionParser::ExpressionParser()
    : parser_{new mup::ParserX(mup::pckCOMMON | mup::pckUNIT | mup::pckNON_COMPLEX |
                               mup::pckSTRING)} {
  // custom operators and functions
  parser_->DefineFun(new Function_substr());
  parser_->DefineFun(new Function_regex_match());
  parser_->DefineFun(new Function_split_part());
  parser_->DefineFun(new Function_int());
  parser_->DefineFun(new Function_float());
  parser_->DefineFun(new Function_double());
  parser_->DefineFun(new Function_str());
  parser_->DefineFun(new Function_bool());
  parser_->DefineInfixOprt(new Operator_not());
}

void ExpressionParser::setStringConstant(const std::string& name,
                                         const std::string& value) {
  parser_->DefineConst(ss_to_ms(name), ss_to_ms(value));
}

void ExpressionParser::setIntConstant(const std::string& name, const int value) {
  parser_->DefineConst(ss_to_ms(name), static_cast<mup::int_type>(value));
}

void ExpressionParser::setExpression(const std::string& expression) {
  parser_->SetExpr(ss_to_ms(expression));
}

std::string ExpressionParser::evalAsString() {
  auto result = evaluate(parser_.get());
  if (result.GetType() != 's') {
    throw std::runtime_error("Expression is not a string");
  }
  return ms_to_ss(result.GetString());
}

int ExpressionParser::evalAsInt() {
  auto result = evaluate(parser_.get());
  if (result.GetType() != 'i') {
    throw std::runtime_error("Expression is not an int");
  }
  return static_cast<int>(result.GetInteger());
}

double ExpressionParser::evalAsDouble() {
  auto result = evaluate(parser_.get());
  if (result.GetType() != 'f') {
    throw std::runtime_error("Expression is not a float/double");
  }
  return static_cast<double>(result.GetFloat());
}

bool ExpressionParser::evalAsBool() {
  auto result = evaluate(parser_.get());
  if (result.GetType() != 'b') {
    throw std::runtime_error("Expression is not a boolean");
  }
  return result.GetBool();
}

}  // namespace import_export

max_stars_repo_name: omnisci/mapd-core

max_issues_repo_name: omnisci/mapd-core

max_forks_repo_name: omnisci/mapd-core


text:
#ifndef __QUERYPARSER_H__
#define __QUERYPARSER_H__

#include <iostream>
#include <sstream>
#include <vector>
#include <iterator>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>

class QueryParserResult
{
  private:
    std::string query;
    std::string croppedQuery;
    std::string sortColumn;
    short sortColumnNumber;
    short sortColumnType;

  public:
    QueryParserResult();
    QueryParserResult(std::string _query);

    std::string getQuery();
    QueryParserResult* setQuery(std::string _query);
    std::string getCroppedQuery();
    QueryParserResult* setCroppedQuery(std::string _croppedQuery);
    std::string getSortColumn();
    QueryParserResult* setSortColumn(std::string _sortColumn);
    short getSortColumnNumber();
    QueryParserResult* setSortColumnNumber(short _sortColumnNumber);
    short getSortColumnType();
    QueryParserResult* setSortColumnType(short _sortColumnType);
};

class QueryParser
{
  private:
    static std::vector<std::string> explodeColumns(const std::string& s, char delim);
  public:
    static QueryParserResult parse(std::string query, bool explicitType, MYSQL *conn);
};

inline QueryParserResult QueryParser::parse(std::string query, bool explicitType, MYSQL *conn)
{
  QueryParserResult result(query);

  boost::regex pattern("SELECT(?:\\s+SQL_NO_CACHE)?\\s+(\\*|[\\w\\.,\\s]*?)\\s+FROM.*(ORDER\\s+BY\\s+([\\w\\.]+))\\s*");
  boost::smatch matches;

  if (boost::regex_match(query, matches, pattern)) {
    //the column given to order by
    result.setSortColumn(matches[3]);

    std::string parsedQuery;

    //ORDER BY ...
    boost::regex orderByPattern(matches[2].str());

    //cut the end of the query
    boost::regex_replace(std::back_inserter(parsedQuery), query.begin(), query.end(), orderByPattern, "");
    result.setCroppedQuery(parsedQuery);

    short i;
    if (matches[1].str() != "*" && explicitType) {
      //iterate over exploded columns and set sortColumnNumber
      std::vector<std::string> columns = QueryParser::explodeColumns(matches[1].str(), ',');
      for (i = 0; i < columns.size(); i++) {
	if (columns[i] == result.getSortColumn()) {
	  result.setSortColumnNumber(i);
	  break;
	}

	if (i == columns.size() - 1) {
	  //TODO: throw an exception, or do some error handling
	}
      }
    } else {
      //execute query with LIMIT 1, then iterate over columns, and set sortColumnNumber and sortColumnType
      std::ostringstream limitedQueryBuilder;
      limitedQueryBuilder<<parsedQuery<<" LIMIT 1";

      MYSQL_RES *queryResult;
      MYSQL_FIELD* field;

      mysql_query(conn, limitedQueryBuilder.str().c_str());
      queryResult = mysql_store_result(conn);

      //tableName.(columnName)
      boost::regex sortColumnPattern("(?:[\\w]*\\.)?([\\w]+)");
      boost::smatch sortColumnMatches;

      i = 0;
      std::ostringstream columnName;
      while (field = mysql_fetch_field(queryResult)) {
	if (boost::regex_match(result.getSortColumn(), sortColumnMatches, sortColumnPattern)) {
	  columnName.str("");
	  columnName<<field->name;
	  if (columnName.str() == sortColumnMatches[1].str()) {
	    result.setSortColumnNumber(i);
	    if (!explicitType) {
	      result.setSortColumnType(field->type);
	    }
	    break;
	  }
	}
	i++;
      }

      mysql_free_result(queryResult);
    }

  }

  return result;
}

inline std::vector<std::string> QueryParser::explodeColumns(const std::string& s, char delim)
{
    std::vector<std::string> result;
    std::istringstream iss(s);

    boost::regex columnPattern("[\\w\\.]+\\s+AS\\s+([\\w\\.]+)");
    boost::smatch matches;

    std::string token;

    while (std::getline(iss, token, delim) )
    {
      boost::trim(token);

      if (boost::regex_match(token, matches, columnPattern)) {
	token = matches[1];
      }

      result.push_back(token);
    }

    return result;
}

inline QueryParserResult::QueryParserResult()
{
  this->query = "";
  this->croppedQuery = "";
  this->sortColumn = "";
  this->sortColumnNumber = 0;
};

inline QueryParserResult::QueryParserResult(std::string _query)
{
  this->query = _query;
  this->croppedQuery = "";
  this->sortColumn = "";
  this->sortColumnNumber = 0;
};

inline std::string QueryParserResult::getQuery()
{
  return this->query;
}

inline QueryParserResult* QueryParserResult::setQuery(std::string _query)
{
  this->query = _query;

  return this;
}

inline std::string QueryParserResult::getCroppedQuery()
{
  return this->croppedQuery;
}

inline QueryParserResult* QueryParserResult::setCroppedQuery(std::string _croppedQuery)
{
  this->croppedQuery = _croppedQuery;

  return this;
}

inline std::string QueryParserResult::getSortColumn()
{
  return this->sortColumn;
}

inline QueryParserResult* QueryParserResult::setSortColumn(std::string _sortColumn)
{
  boost::trim(_sortColumn);
  this->sortColumn = _sortColumn;

  return this;
}

inline short QueryParserResult::getSortColumnNumber()
{
  return this->sortColumnNumber;
}

inline QueryParserResult* QueryParserResult::setSortColumnNumber(short _sortColumnNumber)
{
  this->sortColumnNumber = _sortColumnNumber;

  return this;
}

inline short QueryParserResult::getSortColumnType()
{
  return this->sortColumnType;
}

inline QueryParserResult* QueryParserResult::setSortColumnType(short _sortColumnType)
{
  this->sortColumnType = _sortColumnType;

  return this;
}

#endif


text:
// Copyright (c) 2014 Luca Marturana. All rights reserved.
// Licensed under Apache 2.0, see LICENSE for details

#include <redis3m/connection_pool.h>
#include <redis3m/command.h>
#include <redis3m/utils/resolv.h>
#ifndef NO_BOOST
#include <boost/format.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#endif
#include <redis3m/utils/logging.h>
#include <chrono>
#include <thread>
#include <random>
#ifndef NO_BOOST
#include <boost/algorithm/string/find.hpp>
#include <boost/regex.hpp>
#else
#include <iostream>
#include <sstream>
#include <algorithm>
#include <regex>
#include <numeric>
#endif

using namespace redis3m;

connection_pool::connection_pool(const std::string& sentinel_host,
                                 const std::string& master_name,
                                 unsigned int sentinel_port):
master_name(master_name),
sentinel_port(sentinel_port),
password(""),
_database(0)
{
#ifndef NO_BOOST
    boost::algorithm::split(sentinel_hosts, sentinel_host, boost::is_any_of(","), boost::token_compress_on);
#else //http://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
	std::string s;
	std::istringstream f(sentinel_host.c_str());
	while (std::getline(f, s, ',')) {
		std::cout << s << std::endl;
		sentinel_hosts.push_back(s);
	}
#endif
}

connection::ptr_t connection_pool::get(connection::role_t type)
{
    connection::ptr_t ret;

    // Look for a cached connection
    {
        std::lock_guard<std::mutex> lock(access_mutex);
        std::set<connection::ptr_t>::const_iterator it;
        switch (type) {
            case connection::ANY:
                it = connections.begin();
                break;
            case connection::MASTER:
            case connection::SLAVE:
                it = std::find_if(connections.begin(), connections.end(),[type](connection::ptr_t conn)
                {
                    return conn->_role == type;
                });
                break;
        }
        if (it != connections.end())
        {
            ret = *it;
            connections.erase(it);
        }
    }

    // If no connection found, create a new one
    if (!ret)
    {
        switch (type) {
            case connection::SLAVE:
            {
                ret = create_slave_connection();
                break;
            }
            case connection::ANY:
            {
                try {
                    ret = create_slave_connection();
                    break;
                } catch (const cannot_find_slave& ) {
                    // Go ahead, looking for a master, no break istruction
                    logging::debug("Slave not found, looking for a master");
                }
            }
            case connection::MASTER:
                ret = create_master_connection();
                break;
        }

        // Setup connections selecting db
        if (_database != 0)
        {
            reply r = ret->run(command("SELECT")(std::to_string(_database)));
            if (r.type() == reply::type_t::ERROR)
            {
                throw wrong_database(r.str());
            }
        }
    }
    return ret;
}

void connection_pool::put(connection::ptr_t conn)
{
    if (conn->is_valid())
    {
        std::lock_guard<std::mutex> lock(access_mutex);
        connections.insert(conn);
    }
}

connection::ptr_t connection_pool::sentinel_connection()
{
    for(const std::string& host : sentinel_hosts)
    {
        std::vector<std::string> real_sentinels = resolv::get_addresses(host);
#ifndef NO_BOOST
        logging::debug(boost::str(
                           boost::format("Found %d redis sentinels: %s")
                           % real_sentinels.size()
                           % boost::algorithm::join(real_sentinels, ", ")
                           )
                       );
#else
        std::string msg = "Found " + std::to_string(real_sentinels.size()) + " redis sentinels: " +
                           std::accumulate(std::begin(real_sentinels), std::end(real_sentinels), std::string(),
                                [](const std::string& a, const std::string& b) -> std::string {
                                        return a + (a.length() > 0 ? ", " : "") + b;
                                  });
        logging::debug(msg);
#endif
        for( const std::string& real_sentinel : real_sentinels)
        {
#ifndef NO_BOOST
            logging::debug(boost::str(boost::format("Trying sentinel %s") % real_sentinel));
#else
            logging::debug("Trying sentinel " + real_sentinel);
#endif
            try
            {
                return connection::create(real_sentinel, sentinel_port);
            } catch (const unable_to_connect& )
            {
#ifndef NO_BOOST
                logging::debug(boost::str(boost::format("%s is down") % real_sentinel));
#else
                logging::debug(real_sentinel + " is down");
#endif
            }
        }
    }
    throw cannot_find_sentinel("Cannot find sentinel");
}

connection::role_t connection_pool::get_role(connection::ptr_t conn)
{
	static const
#ifndef NO_BOOST
    boost::regex
#else
	std::regex
#endif
	role_searcher("\r\nrole:([a-z]+)\r\n");

    reply r = conn->run(command("ROLE"));
    std::string role_s;

    if (r.type() == reply::type_t::ERROR
#ifndef NO_BOOST
		&& boost::algorithm::find_first(r.str(),"unknown"))
#else
		&& (r.str().find("unknown") != std::string::npos) )
#endif

    {
        logging::debug("Old redis, doesn't support ROLE command");
        reply r = conn->run(command("INFO") << "replication");
#ifndef NO_BOOST
        boost::smatch results;
        if (boost::regex_search(r.str(), results, role_searcher))
#else
		std::smatch results;
		if (std::regex_search(r.str(), results, role_searcher))
#endif
        {
            role_s = results[1];
        }
    }
    else if (r.type() == reply::type_t::ARRAY)
    {
        role_s = r.elements().at(0).str();
    }

    if (role_s == "master")
    {
        return connection::MASTER;
    }
    else if (role_s == "slave")
    {
        return connection::SLAVE;
    }
    else
    {
        return connection::ANY;
    }
}

bool connection_pool::authenticate(connection::ptr_t conn)
{
    return (conn->run(command("AUTH") << password).type() != reply::type_t::ERROR);
}

connection::ptr_t connection_pool::create_slave_connection()
{
    connection::ptr_t sentinel = sentinel_connection();
    sentinel->append(command("SENTINEL") << "slaves" << master_name );
    reply response = sentinel->get_reply();
    std::vector<reply> slaves(response.elements());

    std::random_device rd;
    std::shuffle(slaves.begin(), slaves.end(), std::mt19937(rd()));

    for (std::vector<reply>::const_iterator it = slaves.begin();
         it != slaves.end(); ++it)
    {
        const std::vector<reply>& properties = it->elements();
        if (properties.at(9).str() == "slave")
        {
            std::string host = properties.at(3).str();
            unsigned int port = std::stoi(properties.at(5).str());
            try
            {
                connection::ptr_t conn = connection::create(host, port);
                if (password != "" && !authenticate(conn))
                {
                    throw authentication_error("Invalid authentication credentials specified");
                }

                connection::role_t role = get_role(conn);
                if (role == connection::SLAVE)
                {
                    conn->_role = role;
                    return conn;
                }
                else
                {
#ifndef NO_BOOST
                    logging::debug(boost::str(boost::format("Error on connection to %s:%d declared to be slave but it's not, waiting") % host % port));
#else
                    std::string msg = "Error on connection to " + host + ":" + std::to_string(port) +
                                      " declared to be slave but it's not, waiting";
                    logging::debug(msg);

#endif
                }
            } catch (const unable_to_connect&)
            {
#ifndef NO_BOOST
                logging::debug(boost::str(boost::format("Error on connection to Slave %s:%d declared to be up") % host % port));
#else
                std::string msg = "Error on connection to Slave " + host + ":" + std::to_string(port) +
                                  " declared to be up";
                logging::debug(msg);
#endif
            }
        }
    }
    throw cannot_find_slave();
}

connection::ptr_t connection_pool::create_master_connection()
{
    unsigned int connection_retries = 0;
    while(connection_retries < 20)
    {
        connection::ptr_t sentinel = sentinel_connection();
        reply masters = sentinel->run(command("SENTINEL")("masters"));
        for(const reply& master : masters.elements())
        {
            if (master.elements().at(1).str() == master_name)
            {
                const std::string& flags = master.elements().at(9).str();
                if (flags == "master")
                {
                    const std::string& master_ip = master.elements().at(3).str();
                    unsigned int master_port = std::stoi(master.elements().at(5).str());

                    try
                    {
                        connection::ptr_t conn = connection::create(master_ip, master_port);
                        if (password != "" && !authenticate(conn))
                        {
                            throw authentication_error("Invalid authentication credentials specified");
                        }

                        connection::role_t role = get_role(conn);
                        if (role == connection::MASTER)
                        {
                            conn->_role = role;
                            return conn;
                        }
                        else
                        {
#ifndef NO_BOOST
                            logging::debug(boost::str(boost::format("Error on connection to %s:%d declared to be master but it's not, waiting") % master_ip % master_port));
#else
                            std::string msg = "Error on connection to " + master_ip + ":" + std::to_string(master_port) +
                                              " declared to be master but it's not, waiting";
                            logging::debug(msg);
#endif //NO_BOOST
                        }
                    } catch (const unable_to_connect&)
                    {
#ifndef NO_BOOST
                        logging::debug(boost::str(boost::format("Error on connection to Master %s:%d declared to be up, waiting") % master_ip % master_port));
#else
                        std::string msg = "Error on connection to Master " + master_ip + ":" +
                                          std::to_string(master_port) + " declared to be up, waiting";
                        logging::debug(msg);
#endif //NO_BOOST
                    }
                }
            }
        }
        connection_retries++;
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
#ifndef NO_BOOST
    throw cannot_find_master(boost::str(boost::format("Unable to find master of name: %s (too much retries") % master_name));
#else
    std::string msg = "Unable to find master of name: " + master_name + " (too many retries)";
    throw cannot_find_master(msg);
#endif
}

template<>
void connection_pool::run_with_connection(std::function<void(connection::ptr_t)> f,
                                connection::role_t conn_type,
                                unsigned int retries)
{
    while (retries > 0)
    {
        try
        {
            connection::ptr_t c = get(conn_type);
            f(c);
            put(c);
            return;
        }
        catch (const connection_error&)
        {
            --retries;
        }
    }
    throw too_much_retries();
}


text:
/**
 * \file
 * \copyright
 * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
 *            Distributed under a Modified BSD License.
 *              See accompanying file LICENSE.txt or
 *              http://www.opengeosys.org/project/license
 */

#include "MathTools.h"

#include <Eigen/Dense>
#include <cmath>

#include "Point3d.h"

namespace MathLib
{

double calcProjPntToLineAndDists(Point3d const& pp, Point3d const& pa,
                                 Point3d const& pb, double& lambda, double& d0)
{
    auto const a = Eigen::Map<Eigen::Vector3d const>(pa.getCoords());
    auto const b = Eigen::Map<Eigen::Vector3d const>(pb.getCoords());
    auto const p = Eigen::Map<Eigen::Vector3d const>(pp.getCoords());

    // g(lambda) = a + lambda v, v = b-a
    Eigen::Vector3d const v = b - a;

    // orthogonal projection: (p - g(lambda))^T * v = 0
    // <=> (a-p - lambda (b-a))^T * (b-a) = 0
    // <=> (a-p)^T * (b-a) = lambda (b-a)^T ) (b-a)
    lambda = (((p - a).transpose() * v) / v.squaredNorm())(0, 0);

    // compute projected point
    Eigen::Vector3d const proj_pnt = a + lambda * v;

    d0 = (proj_pnt - a).norm();

    return (p - proj_pnt).norm();
}

double getAngle(Point3d const& p0, Point3d const& p1, Point3d const& p2)
{
    auto const a = Eigen::Map<Eigen::Vector3d const>(p0.getCoords());
    auto const b = Eigen::Map<Eigen::Vector3d const>(p1.getCoords());
    auto const c = Eigen::Map<Eigen::Vector3d const>(p2.getCoords());
    Eigen::Vector3d const v0 = a - b;
    Eigen::Vector3d const v1 = c - b;

    // apply Cauchy Schwarz inequality
    return std::acos(
        (v0.transpose() * v1 / (v0.norm() * v1.norm()))(0, 0));
}

double scalarTriple(Eigen::Vector3d const& u, Eigen::Vector3d const& v,
                    Eigen::Vector3d const& w)
{
    return u.cross(v).dot(w);
}

}  // namespace MathLib

max_stars_repo_name: yezhigangzju/ogs

max_issues_repo_name: yezhigangzju/ogs

max_forks_repo_name: yezhigangzju/ogs


text:
/*
 *  algorithm.hpp
 *  CBPlatform
 *
 *  Created by Zhu Nengjie on 7/31/13.
 *  Copyright 2013 Bifang technology. All rights reserved.
 *
 */

#ifndef PUBLIC_ALGORITHM_TOOLKIT_H
#define PUBLIC_ALGORITHM_TOOLKIT_H
#include <boost/asio.hpp>
#include <list>
#include <boost/filesystem/convenience.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <fstream>
#include <vector>
#include <sstream>
#include <string>
#include "logger.hpp"
#include <boost/regex.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/algorithm/string.hpp>
#include "memory_buffer.hpp"
//return the index, -1 means not exist
template<class T1, class T2>
int exist_in_vector(const std::vector<T1>& vs, const T2& s)
{
	for(size_t i = 0; i < vs.size(); i++)
	{
		T1 t1 = vs.at(i);
		if(t1 == s)
		{
			return (int)i;
		}
	}
	return -1;
}

template<class T>
bool get_iterator_of_index( T& t1, int index, typename T::iterator& it)
{
	it = t1.begin();
	size_t s = t1.size();
	if(index >= (int)s)
	{
		return false;
	}
	if(index > 0)
	{
		std::advance(it, index);
	}
	return true;
}

template<class T1, class T2>
T2 concatenate_with_separator(const T1& t1, const T2& sep)
{
	T2 s;
	typename T1::const_iterator it;
	for (it = t1.begin(); it != t1.end(); it++)
	{
		if(it != t1.begin())
			s += sep;
		std::stringstream ss;
		ss<<*it;
		s += ss.str();

	}
	return s;
}
template<class T1, class T2>
bool split_by_separator(const T1& s, const T1& sep,  T2& values)
{
	if(s.length() > 0)
	{
		std::vector<T1> vs;
		//boost::split(vs, s, boost::algorithm::is_any_of(sep), boost::algorithm::token_compress_on);
		boost::split_regex(vs, s, boost::regex(sep));
		for(size_t i = 0; i < vs.size(); i++)
		{
			std::stringstream ss;
			ss<<vs.at(i);
			typename T2::value_type t;
			ss>>t;
			values.push_back(t);
		}
	}
	return true;
}

inline bool read_line(std::ifstream& ifs, char* line, size_t length)
{
	if(ifs.getline(line, length))
	{
		size_t line_length = strlen(line);
		if(line[line_length - 1] == '\r')
		{
			line[line_length - 1] = '\0';
		}
		if(line[line_length - 1] == '\n')
		{
			line[line_length - 1] = '\0';
		}
		if((line[line_length - 2] == '\r') && (line[line_length - 1] == '\n') )
		{
			line[line_length - 2] = '\0';
		}
		return true;
	}
	return false;
}

inline void write_line(std::ofstream& ofs, const char* line, size_t length)
{
#ifdef WIN32
	std::string CRLF = "\n";
#elif defined __APPLE__
	std::string CRLF = "\r";
#else
	std::string CRLF = "\n";
#endif

	ofs.write(line, length);
	ofs.write(CRLF.c_str(), CRLF.length());
	ofs.flush();
}

#define WORK_START \
boost::posix_time::ptime time_start = boost::posix_time::microsec_clock::local_time();

#define WORK_FINISH(work_name) \
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();   \
boost::posix_time::millisec_posix_time_system_config::time_duration_type time_elapse = now - time_start; \
boost::uint64_t millisec = time_elapse.total_milliseconds();\
if(millisec >= 200)\
{\
std::stringstream ss;\
ss<<work_name<<" costs ";\
ss<<millisec<<" milliseconds";\
logger_log(__FUNCTION__, LEVEL_WARNING, ss.str().c_str() );\
}

#define TEST_WORK_START(index) \
logger_log(__FUNCTION__, LEVEL_WARNING, "thread %d start...",index);\
boost::posix_time::ptime time_start = boost::posix_time::microsec_clock::local_time();

#define TEST_WORK_FINISH(work_name) \
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();   \
boost::posix_time::millisec_posix_time_system_config::time_duration_type time_elapse = now - time_start; \
boost::uint64_t millisec = time_elapse.total_milliseconds();\
{\
	std::stringstream ss;\
	ss<<work_name<<" costs ";\
	ss<<millisec<<" milliseconds";\
	logger_log(__FUNCTION__, LEVEL_WARNING, ss.str().c_str() );\
}

#ifdef WIN32
inline std::string ws2s(const std::wstring& utf16)
{
	LPSTR pszUtf8 = NULL;
	std::string utf8;

	if (utf16.length() == 0)
	{
		return utf8;
	}

	size_t nLen16 = utf16.length();
	size_t nLen8 = 0;

	if ((nLen8 = WideCharToMultiByte (CP_UTF8, 0, utf16.c_str(), (int)nLen16,
		NULL, 0, 0, 0) + 2) == 2)
	{
		return utf8;
	}

	pszUtf8 = new char [nLen8 + 2];
	if (pszUtf8)
	{
		memset (pszUtf8, 0x00, nLen8 + 2);
		WideCharToMultiByte(CP_UTF8, 0, utf16.c_str(), (int)nLen16, pszUtf8, (int)nLen8, 0, 0);
		utf8 = std::string(pszUtf8);
	}

	delete [] pszUtf8;
	return utf8; //utf8 encoded string
}

inline std::wstring s2ws(const std::string& utf8)
{
	LPWSTR pszUtf16 = NULL;
	std::wstring utf16;

	if (utf8.length() == 0)
	{
		return utf16;
	}

	size_t nLen8 = utf8.length();
	size_t nLen16 = 0;

	if ((nLen16 = MultiByteToWideChar (CP_UTF8, 0, utf8.c_str(), (int)nLen8, NULL, 0)) == 0)
	{
		return utf16;
	}
	pszUtf16 = new wchar_t[nLen16 + 2];
	if (pszUtf16)
	{
		wmemset (pszUtf16, 0x00, nLen16 + 2);
		MultiByteToWideChar (CP_UTF8, 0, utf8.c_str(), (int)nLen8, pszUtf16, (int)nLen16);
		utf16 = std::wstring(pszUtf16);
	}
	delete [] pszUtf16;
	return utf16; //utf16 encoded string
}
#else
inline std::string ws2s(const std::wstring& ws)
{
	std::string curLocale = setlocale(LC_ALL, "");        // curLocale = "C";
#ifdef WIN32
	setlocale(LC_ALL, "chs");
#elif __APPLE__
	setlocale(LC_ALL, "en_US.UTF-8");
#elif LINUX_CENTOS
	setlocale(LC_ALL, "en_US.UTF-8");
#else
	setlocale(LC_ALL, "en_US.UTF-8");
#endif
	const wchar_t* wsource = ws.c_str();
	size_t size = 4 * ws.size() + 4;
	char *dest = new char[size];
	memset(dest, 0, size);
	wcstombs(dest, wsource, size);
	std::string result = dest;
	delete[] dest;
	setlocale(LC_ALL, curLocale.c_str());
	return result;
}

inline std::wstring s2ws(const std::string& s)
{
	std::string curLocale = setlocale(LC_ALL, "");        // curLocale = "C";
#ifdef WIN32
	setlocale(LC_ALL, "chs");
#elif __APPLE__
	setlocale(LC_ALL, "en_US.UTF-8");
	//setlocale(LC_ALL, "zh_CN.GB18030");
#elif LINUX_CENTOS
	setlocale(LC_ALL, "en_US.UTF-8");
#else
	setlocale(LC_ALL, "en_US.UTF-8");
#endif
	//size_t size1 = s.length();
	const char* source = s.c_str();
	//size_t size2 = strlen(source);
	size_t size = s.size() + 2;
	wchar_t *wdest = new wchar_t[size];
	wmemset(wdest, 0, size);
	mbstowcs(wdest, source, size);
	std::wstring result = wdest;
	delete []wdest;
	setlocale(LC_ALL, curLocale.c_str());
	return result;
}
#endif
//-------------------------------------------------------------------------
// Inline functions that convert to/from host and network byte order.
//-------------------------------------------------------------------------

/// @brief Returns true if the current machine is big endian.
/// @return true if big endian or false if little endian.
inline bool is_big_endian() // Big Endian is network byte order.
{
	const long x = 1;
	return *(const char*)&x ? false : true;
}

/// @brief Converts a 32 bit integer to network byte order.
/// @param n The integer in host byte order.
/// @return The integer in network byte order.
inline unsigned int ntoh32(const unsigned int& n)
{
	if(is_big_endian())
		return n;
	return (n & 0x000000ff) << 24 |
	(n & 0x0000ff00) << 8 |
	(n & 0x00ff0000) >> 8 |
	(n & 0xff000000) >> 24;
}

/// @brief Converts a 32 bit integer to host byte order.
/// @param n The integer in network byte order.
/// @return The integer in host byte order.
inline unsigned int hton32(const unsigned int& n)
{
	if(is_big_endian())
		return n;
	return (n & 0x000000ff) << 24 |
	(n & 0x0000ff00) << 8 |
	(n & 0x00ff0000) >> 8 |
	(n & 0xff000000) >> 24;
}

/// @brief Converts a 16 bit integer to network byte order.
/// @param n The integer in host byte order.
/// @return The integer in network byte order.
inline unsigned short ntoh16(const unsigned short& n)
{
	if(is_big_endian())
		return n;
	return (n & 0x00ff) << 8 | (n & 0xff00) >> 8;
}

/// @brief Converts a 16 bit integer to host byte order.
/// @param n The integer in network byte order.
/// @return The integer in host byte order.
inline unsigned short hton16(const unsigned short& n)
{
	if(is_big_endian())
		return n;
	return (n & 0x00ff) << 8 | (n & 0xff00) >> 8;
}

/*
format unsigned int to format as: 00001, 00100,
such as v = 9, length = 8, the return is 00000009
such as v = 9, length = 832, the return is 00000832
*/
inline std::string format_uint32_to_lenght(unsigned int v, int length)
{
	std::stringstream ss;
	ss<<std::setw(length)<<std::setfill('0')<<v;
	return ss.str();
}

template<class out_type,class in_value>
out_type datatype_convert(const in_value & t)
{
	std::stringstream ss;
	if (typeid(t) == typeid(double))
	{
		ss << std::setprecision(12) <<t;
	}
	else
	{
		ss<<t;
	}
	out_type result;
	ss>>result;
	return result;
}
/*
on visual studio,if encounter compile error when compiling a cpp file:
fatal error C1189: #error :  WinSock.h has already been included
you can put #include "algorithm.hpp" or #include <boost/asio.hpp> as the first line of that cpp file
*/
inline std::string uint_ip_2_str(unsigned int uip)
{

		char sip[32];
		boost::system::error_code ec;
		uip = ntohl(uip);
		boost::asio::detail::socket_ops::inet_ntop(AF_INET, &uip, sip, 32, 0, ec);
		return std::string(sip);
}

inline unsigned int str_ip_2_uint(const std::string& sip)
{
	boost::system::error_code ec;
	unsigned int uip;
	boost::asio::detail::socket_ops::inet_pton(AF_INET, sip.c_str(), &uip, NULL, ec);
	return htonl(uip);
}

inline std::string ushort_port_2_str(unsigned short port)
{
	std::stringstream ss;
	ss<<port;
	std::string s = ss.str();
	return s;
}

inline int compare_date(boost::uint64_t t1, boost::uint64_t t2)
{
	time_t tt1 = (time_t)t1;
	time_t tt2 = (time_t)t2;
	int year1, year2, mon1, mon2, day1, day2;
	tm* ptm;
	ptm = localtime(&tt1);
	year1 = ptm->tm_year;
	mon1 = ptm->tm_mon;
	day1 = ptm->tm_mday;

	ptm = localtime(&tt2);
	year2 = ptm->tm_year;
	mon2 = ptm->tm_mon;
	day2 = ptm->tm_mday;
	if(year1 > year2)
	{
		return 1;
	}
	else if(year1 < year2)
	{
		return -1;
	}
	else
	{
		if(mon1 > mon2)
		{
			return 1;
		}
		else if(mon1 < mon2)
		{
			return -1;
		}
		else
		{
			if(day1 > day2)
			{
				return 1;
			}
			else if(day1 < day2)
			{
				return -1;
			}
			else
			{
				return 0;
			}
		}
	}
}

inline bool string_ends_with(const std::string& s1, const std::string& s2)
{
	return boost::ends_with(s1, s2);
}
inline bool string_starts_with(const std::string& s1, const std::string& s2)
{
	return boost::starts_with(s1, s2);
}

template <class datatype>
class remove_elements_match
{
public:
	remove_elements_match(const datatype& dt)
	{
		dt_ = dt;
	}
	bool operator()(const datatype& dt)
	{
		return dt_ == dt;
	}
	datatype dt_;
};
template <class datatype>
void remove_elements(std::list<datatype>& l, std::vector<datatype>& elements)
{
	for(size_t i = 0; i < elements.size(); i++)
	{
		remove_elements_match<datatype> match(elements.at(i));
		l.remove_if(match);
	}
}

inline bool is_not_alnum(char c)
{
	return ((isalpha(c) == 0) && (isdigit(c) == 0) && (c != '_') && (c != '-'));
}
inline bool string_is_alnum_only(const std::string& s)
{
	if(s.length() == 0)
	{
		return false;
	}
	bool b = (find_if(s.begin(), s.end(), is_not_alnum) == s.end());
	return b;
}
inline bool is_not_digit(char c)
{
	return (isdigit(c) == 0);
}
inline bool string_is_number_only(const std::string& s)
{
	std::string tmp = s;
	if(tmp.length() > 0)
	{
		if(isdigit(s.at(0)) == 0) //first char can be -1
		{
			if(s.at(0) != '-')
			{
				return false;
			}
			else
			{
				tmp = s.substr(1, s.length() - 1);
			}
		}
	}
	else
	{
		return false;
	}
	bool b = (find_if(tmp.begin(), tmp.end(), is_not_digit) == tmp.end());
	return b;
}

inline int compare_string_nocase(const std::string& s1, const std::string& s2)
{
	std::string l_s1 = s1, l_s2 = s2;
	boost::to_lower(l_s1);
	boost::to_lower(l_s2);
	return l_s1.compare(l_s2);
}
inline int compare_trimed_string_nocase(const std::string& s1, const std::string& s2)
{
	std::string l_s1 = s1, l_s2 = s2;
	boost::to_lower(l_s1);
	boost::to_lower(l_s2);
	boost::trim(l_s1);
	boost::trim(l_s2);
	return l_s1.compare(l_s2);
}
/*
 3954580968 <--> EBB61DE8
 */
inline std::string format_decimal_string_to_hex_string(const std::string& decimal)
{
	unsigned int dec = datatype_convert<unsigned int>(decimal);
	char hex[16] = {0};
	sprintf(hex, "%x", dec);
	std::string s = hex;
	boost::to_upper(s);
	return s;
}
	/*
	 if len > 0, if the length of decimal string is shorter then the value of len,
	 we will padding 0 before decimal string.
	 */
inline std::string format_hex_string_to_decimal_string(const std::string& hex, int len = 0)
{
	unsigned int dec;
	std::stringstream ss;
	ss << std::hex << hex;
	ss >> dec;
	std::string decimal = datatype_convert<std::string>(dec);
	if(len > 0)
	{
		if((int)decimal.length() < len)
		{
			int padding_len = len - (int)decimal.length();
			for(int i = 0; i < padding_len; i++)
			{
				decimal = std::string("0") + decimal;
			}
		}
	}
	return decimal;
}

/*
 be sure the vector is sorted (can call std::sort(v.begin(), v.end()))

 list can call:
 list l;
 l.sort();
 l.unique();
 */
template<class T>
inline void unique_vector(std::vector<T>& v)
{
	typename std::vector<T>::iterator it_last = std::unique(v.begin(), v.end());
	v.erase(it_last, v.end());
}

/*

 because datatype_convert may including format (such as 12,345,678) in windows platform
 */
inline std::string format_decimal_to_string(unsigned int n)
{
	char str[64] = {0};
	sprintf(str, "%u", n);
	return std::string(str);
}

inline bool double_equal(double d1, double d2)
{
	if(fabs(d1 - d2) < 0.000001)
	{
		return true;
	}
	return false;
}
#endif

max_stars_repo_name: dotphoenix/smppserver

max_issues_repo_name: dotphoenix/smppserver

max_forks_repo_name: dotphoenix/smppserver


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#include <nt2/combinatorial/include/functions/factorial.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/sdk/bench/benchmark.hpp>
#include <nt2/sdk/bench/timing.hpp>
#include <boost/dispatch/meta/as_integer.hpp>
#include <cmath>

using nt2::tag::factorial_;

#define RS(T,V1,V2) (T, (V1) ,(V2))

#undef RS


text:
/**
 * @brief  Compute Particles Scene
 */

// ********************************************************************************
// Including files
// ********************************************************************************

#include <memory>

#include "App.h"
#include "Scene/SceneLoop.h"
#include "SceneParticles.h"

#ifdef __APPLE__
#include <boost/assert.hpp>
#endif

// ********************************************************************************
// Entry point
// ********************************************************************************

int main(
#if true
    void
#else
    int argc, char **argv
#endif
) {

#ifdef __APPLE__
  BOOST_ASSERT_MSG(false, "Can't execute in MacOS");
#endif

  App app("Compute Particles");

  // Create scene
  std::unique_ptr<Scene> scene = std::make_unique<SceneParticles>();

  // Enter the main loop
  return SceneLoop::Run(app, std::move(scene));
}

ext: cc

max_stars_repo_name: mnrn/ReGL

max_issues_repo_name: mnrn/ReGL

max_forks_repo_name: mnrn/ReGL


text:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman
    Copyright (c) 2006 Dan Marsden

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined (BOOST_FUSION_PAIR_TIE_20060812_2058)
#define BOOST_FUSION_PAIR_TIE_20060812_2058

#include <boost/fusion/support/config.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/utility/enable_if.hpp>

namespace boost { namespace fusion {

    template<typename Key, typename T>
    struct pair;

    namespace result_of
    {
        template<typename Key, typename T>
        struct pair_tie
        {
            typedef fusion::pair<Key, T&> type;
        };
    }

    template<typename Key, typename T>
    BOOST_FUSION_GPU_ENABLED
    typename disable_if<is_const<T>, typename result_of::pair_tie<Key, T>::type>::type
    pair_tie(T& t)
    {
        return typename result_of::pair_tie<Key, T>::type(t);
    }

    template<typename Key, typename T>
    BOOST_FUSION_GPU_ENABLED
    typename result_of::pair_tie<Key, T const>::type
    pair_tie(T const& t)
    {
        return typename result_of::pair_tie<Key, T const>::type(t);
    }
}}

#endif

max_stars_repo_name: bowlofstew/omim

max_issues_repo_name: bowlofstew/omim

max_forks_repo_name: bowlofstew/omim


text:
//-----------------------------------------------------------------------------
// Copyright (c) 2017-2018 Benjamin Buch
//
// https://github.com/bebuch/disposer
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
//-----------------------------------------------------------------------------
#ifndef _disposer__tool__get_or_default__hpp_INCLUDED_
#define _disposer__tool__get_or_default__hpp_INCLUDED_

#include <boost/hana/count_if.hpp>
#include <boost/hana/size.hpp>

namespace disposer{

	template < typename Tuple, typename Predicate, typename Default >
	constexpr auto get_or_default(
		Tuple&& tuple,
		Predicate&& predicate,
		Default&& default_value
	){
		auto const count = hana::count_if(tuple, predicate);
		static_assert(count <= hana::size_c< 1 >,
			"more than one argument with this tag");

		auto result = hana::find_if(static_cast< Tuple&& >(tuple),
			static_cast< Predicate&& >(predicate));
		if constexpr(auto const found = result != hana::nothing; found){
			return *static_cast< decltype(result)&& >(result);
		}else{
			return static_cast< Default&& >(default_value);
		}
	}

}

#endif

max_stars_repo_name: bebuch/disposer

max_issues_repo_name: bebuch/disposer

max_forks_repo_name: bebuch/disposer