text: #include <boost/mpl/aux_/begin_end_impl.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


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

#ifndef IROHA_TEST_FRAMEWORK_EXECUTOR_ITF_HELPER_HPP
#define IROHA_TEST_FRAMEWORK_EXECUTOR_ITF_HELPER_HPP

#include <memory>

#include <boost/mpl/at.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/map.hpp>
#include "common/result.hpp"
#include "interfaces/commands/command.hpp"
#include "interfaces/queries/query.hpp"

#include "interfaces/query_responses/account_asset_response.hpp"
#include "interfaces/query_responses/account_detail_response.hpp"
#include "interfaces/query_responses/account_response.hpp"
#include "interfaces/query_responses/asset_response.hpp"
#include "interfaces/query_responses/block_error_response.hpp"
#include "interfaces/query_responses/block_query_response.hpp"
#include "interfaces/query_responses/block_response.hpp"
#include "interfaces/query_responses/engine_receipts_response.hpp"
#include "interfaces/query_responses/error_query_response.hpp"
#include "interfaces/query_responses/pending_transactions_page_response.hpp"
#include "interfaces/query_responses/query_response.hpp"
#include "interfaces/query_responses/role_permissions.hpp"
#include "interfaces/query_responses/roles_response.hpp"
#include "interfaces/query_responses/signatories_response.hpp"
#include "interfaces/query_responses/transactions_page_response.hpp"
#include "interfaces/query_responses/transactions_response.hpp"

namespace iroha {
  namespace integration_framework {
    namespace detail {

      /**
       * A type map from specific query to the corresponding response.
       *
       * Is used only to get a default expected response type for some query.
       * The queries may also return different responses, and if you expect a
       * different response type, you should either use the interface of
       * conversion functions to specify it, or extract it from the response
       * variant manually.
       */
      typedef boost::mpl::map<
          boost::mpl::pair<shared_model::interface::GetAccount,
                           shared_model::interface::AccountResponse>,
          boost::mpl::pair<shared_model::interface::GetSignatories,
                           shared_model::interface::SignatoriesResponse>,
          boost::mpl::pair<shared_model::interface::GetAccountTransactions,
                           shared_model::interface::TransactionsResponse>,
          boost::mpl::pair<shared_model::interface::GetAccountAssetTransactions,
                           shared_model::interface::TransactionsResponse>,
          boost::mpl::pair<shared_model::interface::GetTransactions,
                           shared_model::interface::TransactionsResponse>,
          boost::mpl::pair<shared_model::interface::GetAccountAssets,
                           shared_model::interface::AccountAssetResponse>,
          boost::mpl::pair<shared_model::interface::GetAccountDetail,
                           shared_model::interface::AccountDetailResponse>,
          boost::mpl::pair<shared_model::interface::GetRoles,
                           shared_model::interface::RolesResponse>,
          boost::mpl::pair<shared_model::interface::GetRolePermissions,
                           shared_model::interface::RolePermissionsResponse>,
          boost::mpl::pair<shared_model::interface::GetAssetInfo,
                           shared_model::interface::AssetResponse>,
          boost::mpl::pair<
              shared_model::interface::GetPendingTransactions,
              shared_model::interface::PendingTransactionsPageResponse>,
          boost::mpl::pair<shared_model::interface::GetBlock,
                           shared_model::interface::BlockResponse>,
          boost::mpl::pair<shared_model::interface::GetEngineReceipts,
                           shared_model::interface::EngineReceiptsResponse>>
          SpecificQueryResponses;

      /// true for specific commands
      template <typename T>
      constexpr bool isSpecificCommand = boost::mpl::contains<
          shared_model::interface::Command::CommandVariantType::types,
          const std::decay_t<T> &>::type::value;

      /// true for specific queries
      template <typename T>
      constexpr bool isSpecificQuery = boost::mpl::contains<
          shared_model::interface::Query::QueryVariantType::types,
          const std::decay_t<T> &>::type::value;

      template <typename T>
      std::enable_if_t<isSpecificQuery<T>, const T &> getInterfaceQueryRef(
          const T &query) {
        return query;
      }

      template <typename T, typename SpecificQuery = typename T::ModelType>
      std::enable_if_t<isSpecificQuery<SpecificQuery>, const SpecificQuery &>
      getInterfaceQueryRef(const T &query) {
        return static_cast<const SpecificQuery &>(query);
      }

      template <typename T>
      using InterfaceQuery = decltype(getInterfaceQueryRef(std::declval<T>()));

      /// response for specific query
      template <typename SpecificQuery,
                typename = std::enable_if_t<isSpecificQuery<SpecificQuery>>>
      using GetSpecificQueryResponse =
          typename boost::mpl::at<SpecificQueryResponses,
                                  std::decay_t<SpecificQuery>>::type;

      /**
       * Try to extract the given specific response from a general query
       * response.
       * @tparam SpecificQueryResponse The specific response type to extract.
       * @param query_result The general query response.
       * @return The specific response if the general one has it, the general
       * response if not.
       */
      template <typename SpecificQueryResponse>
      iroha::expected::Result<const SpecificQueryResponse &,
                              iroha::ametsuchi::QueryExecutorResult &>
      convertToSpecificQueryResponse(
          iroha::ametsuchi::QueryExecutorResult &query_result) {
        if (auto specific_query_response =
                boost::strict_get<const SpecificQueryResponse &>(
                    &query_result->get())) {
          return iroha::expected::makeValue<const SpecificQueryResponse &>(
              *specific_query_response);
        }
        return iroha::expected::makeError<
            iroha::ametsuchi::QueryExecutorResult &>(query_result);
      }
    }  // namespace detail
  }    // namespace integration_framework
}  // namespace iroha

#endif  // IROHA_TEST_FRAMEWORK_EXECUTOR_ITF_HELPER_HPP

max_stars_repo_name: Insafin/iroha

max_issues_repo_name: Insafin/iroha

max_forks_repo_name: Insafin/iroha


text:
#ifndef PERSPECTIVE_PROJECTION_HPP
#define PERSPECTIVE_PROJECTION_HPP

#include <Eigen/Core>

#include "log.hpp"
#include "projection.hpp"

class PerspectiveProjection : public Projection {
  public:
    PerspectiveProjection(double left, double right, double bottom, double top, double near, double far);

  private:
    void generateTransformation();
};

#endif // PERSPECTIVE_PROJECTION_HPP

max_stars_repo_name: matheusportela/black-hole-ray-tracer

max_issues_repo_name: matheusportela/black-hole-ray-tracer

max_forks_repo_name: matheusportela/black-hole-ray-tracer


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
//==============================================================================
#ifndef BOOST_SIMD_SDK_SIMD_EXTENSIONS_X86_XOP_HPP_INCLUDED
#define BOOST_SIMD_SDK_SIMD_EXTENSIONS_X86_XOP_HPP_INCLUDED

#if defined(__XOP__)
#  ifndef BOOST_SIMD_HAS_XOP_SUPPORT
#    define BOOST_SIMD_HAS_XOP_SUPPORT
#  endif
#elif defined(BOOST_SIMD_HAS_XOP_SUPPORT) && !defined(_MSC_VER)
#  undef BOOST_SIMD_HAS_XOP_SUPPORT
#endif

#if defined(BOOST_SIMD_HAS_XOP_SUPPORT) && !defined(BOOST_SIMD_HAS_FMA4_SUPPORT)
#  define BOOST_SIMD_HAS_FMA4_SUPPORT
#endif

#if !defined(BOOST_SIMD_DETECTED) && defined(BOOST_SIMD_HAS_XOP_SUPPORT)

////////////////////////////////////////////////////////////////////////////////
// XOP extensions flags
////////////////////////////////////////////////////////////////////////////////
#define BOOST_SIMD_DETECTED
#define BOOST_SIMD_XOP
#define BOOST_SIMD_SSE_FAMILY
#define BOOST_SIMD_STRING             "XOP"
#define BOOST_SIMD_STRING_LIST        "SSE2 SSE3 SSE4A SSSE3 SSE4_1 SSE4_2 AVX FMA4 XOP"
#define BOOST_SIMD_BYTES              32
#define BOOST_SIMD_BITS               256
#define BOOST_SIMD_CARDINALS          (2)(4)(8)(16)(32)
#define BOOST_SIMD_TAG_SEQ            (::boost::simd::tag::avx_)(::boost::simd::tag::sse_)
#define BOOST_SIMD_DEFAULT_EXTENSION  ::boost::simd::tag::avx_
#define BOOST_SIMD_DEFAULT_SITE       ::boost::simd::tag::xop_

// XOP header not standardized
#ifdef _MSC_VER
#include <intrin.h>
#else
#include <x86intrin.h>
#include <xopintrin.h>
#endif

#include <boost/simd/sdk/simd/extensions/meta/sse.hpp>
#include <boost/simd/sdk/simd/extensions/meta/avx.hpp>

#endif
#endif


text:
#define BOOST_TEST_MODULE "test_omp_external_distance_interaction"

#ifdef BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#else
#include <boost/test/included/unit_test.hpp>
#endif

#include <test/util/utility.hpp>

#include <mjolnir/math/math.hpp>
#include <mjolnir/core/BoundaryCondition.hpp>
#include <mjolnir/core/SimulatorTraits.hpp>
#include <mjolnir/core/AxisAlignedPlane.hpp>
#include <mjolnir/forcefield/external/LennardJonesWallPotential.hpp>
#include <mjolnir/omp/System.hpp>
#include <mjolnir/omp/UnlimitedGridCellList.hpp>
#include <mjolnir/omp/ExternalDistanceInteraction.hpp>
#include <mjolnir/util/make_unique.hpp>

BOOST_AUTO_TEST_CASE(omp_ExternalDistacne_calc_force)
{
    namespace test = mjolnir::test;

    constexpr double tol = 1e-8;
    mjolnir::LoggerManager::set_default_logger("test_omp_external_distance_interaction.log");

    using seq_traits_type  = mjolnir::SimulatorTraits      <double, mjolnir::UnlimitedBoundary>;
    using omp_traits_type  = mjolnir::OpenMPSimulatorTraits<double, mjolnir::UnlimitedBoundary>;

    using real_type        = typename omp_traits_type::real_type;
    using coordinate_type  = typename omp_traits_type::coordinate_type;
    using boundary_type    = typename omp_traits_type::boundary_type;
    using topology_type    = mjolnir::Topology;

    using potential_type   = mjolnir::LennardJonesWallPotential<real_type>;
    using parameter_type   = typename potential_type::parameter_type;

    using omp_system_type      = mjolnir::System<omp_traits_type>;
    using omp_shape_type       = mjolnir::AxisAlignedPlane<omp_traits_type, mjolnir::PositiveZDirection<omp_traits_type>>;
    using omp_interaction_type = mjolnir::ExternalDistanceInteraction<omp_traits_type, potential_type, omp_shape_type>;

    using seq_system_type      = mjolnir::System<seq_traits_type>;
    using seq_shape_type       = mjolnir::AxisAlignedPlane<seq_traits_type, mjolnir::PositiveZDirection<seq_traits_type>>;
    using seq_interaction_type = mjolnir::ExternalDistanceInteraction<seq_traits_type, potential_type, seq_shape_type>;

    const int max_number_of_threads = omp_get_max_threads();
    BOOST_TEST_WARN(max_number_of_threads > 2);
    BOOST_TEST_MESSAGE("maximum number of threads = " << max_number_of_threads);

    const std::size_t N_particle = 64;
    std::vector<std::pair<std::size_t, parameter_type>> parameters(N_particle);
    for(std::size_t i=0; i<N_particle; ++i)
    {
        parameters.emplace_back(i, parameter_type(1.0, 1.0));
    }
    const potential_type potential(2.5, parameters);
    topology_type topol(N_particle);
    topol.construct_molecules();

    std::mt19937 rng(123456789);

    for(int num_thread=1; num_thread<=max_number_of_threads; ++num_thread)
    {
        omp_set_num_threads(num_thread);
        BOOST_TEST_MESSAGE("maximum number of threads = " << omp_get_max_threads());

        omp_system_type omp_sys(N_particle, boundary_type{});
        seq_system_type seq_sys(N_particle, boundary_type{});
        test::clear_everything(omp_sys);
        test::clear_everything(seq_sys);

        for(std::size_t i=0; i<omp_sys.size(); ++i)
        {
            const auto i_x = i % 4;
            const auto i_y = i / 4;
            const auto i_z = i / 16;

            omp_sys.position(i) = mjolnir::math::make_coordinate<coordinate_type>(i_x*2.0, i_y*2.0, i_z*2.0);
        }

        test::apply_random_perturbation(omp_sys, rng, 0.1);

        // init sequential one with the same coordinates
        for(std::size_t i=0; i<seq_sys.size(); ++i)
        {
            seq_sys.mass(i)     = omp_sys.mass(i);
            seq_sys.position(i) = omp_sys.position(i);
            seq_sys.velocity(i) = omp_sys.velocity(i);
            seq_sys.force(i)    = omp_sys.force(i);
            seq_sys.name(i)     = omp_sys.name(i);
            seq_sys.group(i)    = omp_sys.group(i);
        }

        omp_shape_type omp_xyplane(0.0);
        seq_shape_type seq_xyplane(0.0);

        omp_xyplane.initialize(omp_sys, potential);
        seq_xyplane.initialize(seq_sys, potential);

        omp_interaction_type omp_interaction(std::move(omp_xyplane), potential_type(potential));
        seq_interaction_type seq_interaction(std::move(seq_xyplane), potential_type(potential));

        omp_interaction.initialize(omp_sys);
        seq_interaction.initialize(seq_sys);

        test::check_force_consistency              (omp_sys, omp_interaction, seq_sys, seq_interaction, tol);
        test::check_force_and_energy_consistency   (omp_sys, omp_interaction, seq_sys, seq_interaction, tol);
        test::check_energy_consistency             (omp_sys, omp_interaction, seq_sys, seq_interaction, tol);
    }
}

ext: cpp

max_stars_repo_name: ToruNiina/Mjolnir

max_issues_repo_name: Mjolnir-MD/Mjolnir

max_forks_repo_name: Mjolnir-MD/Mjolnir


text:
// iorate::variant
//
// Copyright iorate 2017.
// 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)

#define BOOST_TEST_DYN_LINK

#include <boost/test/unit_test.hpp>

#include <string>
#include <type_traits>
#include <utility>
#include "common.hpp"

BOOST_AUTO_TEST_CASE(copy_assignment)
{
    {
        iorate::variant<int, double> v1 = 42;
        iorate::variant<int, double> v2 = 65;
        v1 = v2;
        BOOST_TEST(iorate::get<0>(v1) == 65);
    }
    {
        iorate::variant<int, double> v1 = 42;
        iorate::variant<int, double> v2 = 12.0;
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
    }
    {
        iorate::variant<int, std::string> v1 = 42;
        iorate::variant<int, std::string> v2 = "foo";
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1) == "foo");
    }
    {
        iorate::variant<int, susp_copy_move> v1 = 42;
        iorate::variant<int, susp_copy_move> v2(std::in_place_index<1>, 65);
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1).value == 65);
    }
    {
        iorate::variant<int, bad_copy_move> v1 = 42;
        iorate::variant<int, bad_copy_move> v2(std::in_place_index<1>);
        BOOST_CHECK_THROW(v1 = v2, int);
        BOOST_TEST(iorate::get<0>(v1) == 42);
    }
    {
        iorate::variant<susp_copy_move, double> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, double> v2 = 12.0;
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
        force_backup(v1, 42);
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
    }
    {
        iorate::variant<susp_copy_move, susp_copy_move> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, susp_copy_move> v2(std::in_place_index<1>, 65);
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1).value == 65);
        force_backup(v1, 42);
        v1 = v2;
        BOOST_TEST(iorate::get<1>(v1).value == 65);
    }
    {
        iorate::variant<susp_copy_move, bad_copy_move> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, bad_copy_move> v2(std::in_place_index<1>);
        BOOST_CHECK_THROW(v1 = v2, int);
        BOOST_TEST(iorate::get<0>(v1).value == 42);
        BOOST_CHECK_THROW(v1 = v2, int);
        BOOST_TEST(iorate::get<0>(v1).value == 42);
    }
}

BOOST_AUTO_TEST_CASE(move_assignment)
{
    {
        static_assert(std::is_nothrow_move_assignable_v<iorate::variant<int, double>>);
        iorate::variant<int, double> v1 = 42;
        iorate::variant<int, double> v2 = 65;
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<0>(v1) == 65);
    }
    {
        iorate::variant<int, double> v1 = 42;
        iorate::variant<int, double> v2 = 12.0;
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
    }
    {
        static_assert(std::is_nothrow_move_assignable_v<iorate::variant<int, std::string>>);
        iorate::variant<int, std::string> v1 = 42;
        iorate::variant<int, std::string> v2 = "foo";
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1) == "foo");
    }
    {
        static_assert(!std::is_nothrow_move_assignable_v<iorate::variant<int, susp_copy_move>>);
        iorate::variant<int, susp_copy_move> v1 = 42;
        iorate::variant<int, susp_copy_move> v2(std::in_place_index<1>, 65);
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1).value == 65);
        BOOST_TEST(iorate::get<1>(v2).value == 0);
    }
    {
        static_assert(!std::is_nothrow_move_assignable_v<iorate::variant<int, bad_copy_move>>);
        iorate::variant<int, bad_copy_move> v1 = 42;
        iorate::variant<int, bad_copy_move> v2(std::in_place_index<1>);
        BOOST_CHECK_THROW(v1 = std::move(v2), int);
        BOOST_TEST(iorate::get<0>(v1) == 42);
    }
    {
        static_assert(!std::is_nothrow_move_assignable_v<iorate::variant<susp_copy_move, double>>);
        iorate::variant<susp_copy_move, double> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, double> v2 = 12.0;
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
        force_backup(v1, 42);
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1) == 12.0);
    }
    {
        static_assert(!std::is_nothrow_move_assignable_v<iorate::variant<susp_copy_move, susp_copy_move>>);
        iorate::variant<susp_copy_move, susp_copy_move> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, susp_copy_move> v2(std::in_place_index<1>, 65);
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1).value == 65);
        BOOST_TEST(iorate::get<1>(v2).value == 0);
        force_backup(v1, 42);
        v2.emplace<1>(65);
        v1 = std::move(v2);
        BOOST_TEST(iorate::get<1>(v1).value == 65);
        BOOST_TEST(iorate::get<1>(v2).value == 0);
    }
    {
        static_assert(!std::is_nothrow_move_assignable_v<iorate::variant<susp_copy_move, bad_copy_move>>);
        iorate::variant<susp_copy_move, bad_copy_move> v1(std::in_place_index<0>, 42);
        iorate::variant<susp_copy_move, bad_copy_move> v2(std::in_place_index<1>);
        BOOST_CHECK_THROW(v1 = std::move(v2), int);
        BOOST_TEST(iorate::get<0>(v1).value == 42);
        BOOST_CHECK_THROW(v1 = std::move(v2), int);
        BOOST_TEST(iorate::get<0>(v1).value == 42);
    }
}

BOOST_AUTO_TEST_CASE(assignment)
{
    {
        iorate::variant<int, double> v = 42;
        static_assert(noexcept(v = 65));
        v = 65;
        BOOST_TEST(iorate::get<0>(v) == 65);
    }
    {
        iorate::variant<int, double> v = 42;
        static_assert(noexcept(v = 12.0));
        v = 12.0;
        BOOST_TEST(iorate::get<1>(v) == 12.0);
    }
    {
        iorate::variant<int, std::string> v = 42;
        static_assert(!noexcept(v = "foo"));
        v = "foo";
        BOOST_TEST(iorate::get<1>(v) == "foo");
    }
    {
        iorate::variant<int, bad_copy_move> v = 42;
        static_assert(!noexcept(v = bad_copy_move()));
        BOOST_CHECK_THROW(v = bad_copy_move(), int);
        BOOST_TEST(iorate::get<0>(v) == 42);
    }
    {
        iorate::variant<susp_copy_move, double> v(std::in_place_index<0>, 42);
        static_assert(noexcept(v = 12.0));
        v = 12.0;
        BOOST_TEST(iorate::get<1>(v) == 12.0);
        force_backup(v, 42);
        v = 12.0;
        BOOST_TEST(iorate::get<1>(v) == 12.0);
    }
    {
        iorate::variant<susp_copy_move, std::string> v(std::in_place_index<0>, 42);
        static_assert(!noexcept(v = "foo"));
        v = "foo";
        BOOST_TEST(iorate::get<1>(v) == "foo");
        force_backup(v, 42);
        v = "foo";
        BOOST_TEST(iorate::get<1>(v) == "foo");
    }
    {
        iorate::variant<susp_copy_move, bad_copy_move> v(std::in_place_index<0>, 42);
        static_assert(!noexcept(v = bad_copy_move()));
        BOOST_CHECK_THROW(v = bad_copy_move(), int);
        BOOST_TEST(iorate::get<0>(v).value == 42);
        BOOST_CHECK_THROW(v = bad_copy_move(), int);
        BOOST_TEST(iorate::get<0>(v).value == 42);
    }
}

max_stars_repo_name: iorate/variant

max_issues_repo_name: iorate/variant

max_forks_repo_name: iorate/variant


text:
// Copyright 2020 Jan Feitsma (Falcons)
// SPDX-License-Identifier: Apache-2.0
#include "RtDB2StorageLMDB.h"

#include <boost/filesystem.hpp>
#include <sstream>
#include "../RtDB2ErrorCode.h"
#include "RtDB2Definitions.h"
#include "../serializer/RtDB2Serializer.h"

RtDB2LMDB::RtDB2LMDB(std::string parent_path, std::string name) : is_initialized_(false)
{
    std::stringstream file_path;
    file_path << parent_path;
    file_path << "/";
    file_path << name;

    storage_path_ = file_path.str();

    init_storage();
}

RtDB2LMDB::~RtDB2LMDB() {
    if (is_initialized_) {
        mdb_dbi_close(env_, dbi_);
        mdb_env_close(env_);
    }
}

int RtDB2LMDB::init_operation(bool read_operation) {
    int err;
    if (!is_initialized_) {
        err = read_operation ? init_storage_if_exists() : init_storage();
        if (err != RTDB2_SUCCESS)
            return err;
    }

    int dead;
    err = mdb_reader_check(env_, &dead);
    if (dead != 0)
        RTDB_ERROR("[LMDB] Cleared %d reader stalls", dead);
    return err;
}

int RtDB2LMDB::init_storage() {
    // Create the folder used to store the databases
    if (!boost::filesystem::exists(storage_path_))
        boost::filesystem::create_directories(storage_path_);

    // Creating environment
    mdb_env_create(&env_);
    // This should be checked, the db may be resized but there must be no active transactions
    mdb_env_set_mapsize(env_, 100 * 1024 * 1024);
    // Reason for adding MDB_NOTLS: https://github.com/ximion/appstream-generator/issues/21
    mdb_env_open(env_, storage_path_.c_str(), MDB_WRITEMAP | MDB_NOSYNC | MDB_NOMETASYNC | MDB_NOTLS, 0664);

    MDB_txn *txn;
    // Creating the database
    int err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::init_storage/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }
    mdb_dbi_open(txn, NULL, MDB_CREATE, &dbi_);
    mdb_txn_commit(txn);

    is_initialized_ = true;

    return RTDB2_SUCCESS;
}

int RtDB2LMDB::init_storage_if_exists() {
    if (!boost::filesystem::exists(storage_path_))
    {
        return RTDB2_STORAGE_DOES_NOT_EXISTS;
    }

    return init_storage();
}

int RtDB2LMDB::insert(std::string key, std::string binary_value) {
    int err;
    if ((err = init_operation(false)) != RTDB2_SUCCESS)
        return err;

    MDB_val mdb_key, mdb_value;
    MDB_txn *txn;

    mdb_key.mv_size = key.size();
    mdb_key.mv_data = const_cast<char*>(key.c_str());

    mdb_value.mv_size = binary_value.size();
    mdb_value.mv_data = const_cast<char*>(binary_value.c_str());

    err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::insert/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }
    mdb_put(txn, dbi_, &mdb_key, &mdb_value, 0);
    mdb_txn_commit(txn);
    return RTDB2_SUCCESS;
}

int RtDB2LMDB::fetch(std::string key, std::string& value) {
    int err;
    if (init_operation(true) != RTDB2_SUCCESS)
        return RTDB2_KEY_NOT_FOUND;

    MDB_txn *txn;
    MDB_val obj_key, obj_data;

    obj_key.mv_size = key.size();
    obj_key.mv_data = const_cast<char*>(key.c_str());

    err = mdb_txn_begin(env_, NULL, MDB_RDONLY, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::fetch/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }
    err = mdb_get(txn, dbi_, &obj_key, &obj_data);
    mdb_txn_abort(txn);

    if (err)
        return RTDB2_KEY_NOT_FOUND;
    value = std::string(static_cast<char*>(obj_data.mv_data), obj_data.mv_size);
    return 0;
}

int RtDB2LMDB::fetch_and_clear(std::string key, std::string& value) {
    int err;
    if (init_operation(false) != RTDB2_SUCCESS)
        return RTDB2_KEY_NOT_FOUND;

    MDB_txn *txn;
    MDB_val obj_key, obj_data;

    obj_key.mv_size = key.size();
    obj_key.mv_data = const_cast<char*>(key.c_str());

    err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::fetch_and_clear/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }
    err = mdb_get(txn, dbi_, &obj_key, &obj_data);
    mdb_del(txn, dbi_, &obj_key, NULL);
    mdb_txn_commit(txn);

    if (err)
        return RTDB2_KEY_NOT_FOUND;
    value = std::string(static_cast<char*>(obj_data.mv_data), obj_data.mv_size);

    return 0;
}

int RtDB2LMDB::fetch_all_data(std::vector<std::pair<std::string, std::string> >& values) {
    if (init_operation(true) != RTDB2_SUCCESS)
        return RTDB2_KEY_NOT_FOUND;

    MDB_txn *txn;
    MDB_cursor *cursor;
    MDB_val key, data;

    int err = mdb_txn_begin(env_, NULL, MDB_RDONLY, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::fetch_all_data/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }
    mdb_cursor_open(txn, dbi_, &cursor);
    while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
        values.push_back(std::pair<std::string, std::string>(
                std::string(static_cast<char*>(key.mv_data), key.mv_size),
                std::string(static_cast<char*>(data.mv_data), data.mv_size))
        );
    }
    mdb_cursor_close(cursor);
    mdb_txn_abort(txn);
    return 0;
}

// Append syncPoint to the list under 'key' in this class' LMDB
int RtDB2LMDB::append_to_sync_list(const std::string& key, const RtDB2SyncPoint& syncPoint) {
    if (init_operation(false) != RTDB2_SUCCESS)
        return RTDB2_KEY_NOT_FOUND;

    int err;
    MDB_txn *txn;

    err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::append_to_sync_list/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }

    MDB_val obj_key, obj_data;
    obj_key.mv_size = key.size();
    obj_key.mv_data = const_cast<char*>(key.c_str());
    err = mdb_get(txn, dbi_, &obj_key, &obj_data);

    std::vector<RtDB2SyncPoint> syncPoints;

    if(!err) // key is present, get list back
    {
        std::string raw_data = std::string(static_cast<char*>(obj_data.mv_data), obj_data.mv_size);
        err = RtDB2Serializer::deserialize(raw_data, syncPoints);
        if (err) return err;
    }
    else
    {
        // Key does not exist, reset obj_data
        obj_data.mv_size = 0;
        obj_data.mv_data = 0;
    }
    // Append syncPoint to the (optionally existing) list
    syncPoints.push_back(syncPoint);

    // Serialize syncPoints before writing
    std::string serialized_data;
    err = RtDB2Serializer::serialize(syncPoints, serialized_data);
    if (err) return err;

    // Update obj_data with new size.
    obj_data.mv_size = serialized_data.size();
    obj_data.mv_data = const_cast<char*>(serialized_data.c_str());

    // Put back the obj_data with the syncPoint appended
    mdb_put(txn, dbi_, &obj_key, &obj_data, 0);

    mdb_txn_commit(txn);

    return RTDB2_SUCCESS;
}

int RtDB2LMDB::get_and_clear_sync_list(const std::string& key, std::vector<RtDB2SyncPoint>& list)
{
    if (init_operation(false) != RTDB2_SUCCESS)
            return RTDB2_KEY_NOT_FOUND;

    int err;
    MDB_txn *txn;

    err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::get_and_clear_sync_list/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }

    MDB_val obj_key, obj_data;
    obj_key.mv_size = key.size();
    obj_key.mv_data = const_cast<char*>(key.c_str());

    err = mdb_get(txn, dbi_, &obj_key, &obj_data);

    if(err == 0) // key is present, get list back
    {
        std::string raw_data = std::string(static_cast<char*>(obj_data.mv_data), obj_data.mv_size);
        err = RtDB2Serializer::deserialize(raw_data, list);
        if (err) return err;
    }

    mdb_del(txn, dbi_, &obj_key, NULL);

    mdb_txn_commit(txn);

    return RTDB2_SUCCESS;
}

int RtDB2LMDB::insert_batch(const std::vector<std::pair<std::string, std::string> >& values) {
    int err;
    if ((err = init_operation(false)) != RTDB2_SUCCESS)
        return err;

    MDB_txn *txn;
    MDB_cursor *cursor;
    err = mdb_txn_begin(env_, NULL, 0, &txn);
    if (err != 0)
    {
        // TODO show details, link, ... better use std exceptions?
        RTDB_ERROR("RtDB2LMDB::insert_batch/mdb_txn_begin returned error code %d", err);
        return RTDB2_INTERNAL_MDB_ERROR;
    }

    mdb_cursor_open(txn, dbi_, &cursor);

    std::vector<std::pair<std::string, std::string> >::const_iterator entry;
    for (entry = values.begin(); entry != values.end(); entry++) {
        MDB_val mdb_key, mdb_value;
        mdb_key.mv_size = entry->first.size();
        mdb_key.mv_data = const_cast<char*>(entry->first.c_str());

        mdb_value.mv_size = entry->second.size();
        mdb_value.mv_data = const_cast<char*>(entry->second.c_str());

        mdb_cursor_put(cursor, &mdb_key, &mdb_value, 0);
    }
    mdb_cursor_close(cursor);
    mdb_txn_commit(txn);
    return 0;
}

std::ostream& RtDB2LMDB::dump(std::ostream& os) {
    if (init_operation(true) != RTDB2_SUCCESS)
        return os;

    MDB_txn *txn;
    MDB_cursor *cursor;
    MDB_val key, data;

    mdb_txn_begin(env_, NULL, MDB_RDONLY, &txn); // TODO check return code

    mdb_cursor_open(txn, dbi_, &cursor);
    while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
        std::string obj_key(static_cast<char*>(key.mv_data), key.mv_size);
        std::string obj_data(static_cast<char*>(data.mv_data), data.mv_size);
        os << "key: " << obj_key << ", data: " << obj_data << std::endl;
    }
    mdb_cursor_close(cursor);
    mdb_txn_abort(txn);
    return os;
}

max_stars_repo_name: Falcons-Robocup/code

max_issues_repo_name: Falcons-Robocup/code

max_forks_repo_name: Falcons-Robocup/code


text:
#pragma once

// Only there to split the client.cpp file
// Should be included only there

#include <boost/version.hpp>

#include <deque>
#include <atomic>

namespace beauty
{
// --------------------------------------------------------------------------
template<bool SSL>
class session_client : public std::enable_shared_from_this<session_client<SSL>>
{
public:
    using stream_type = std::conditional_t<SSL,
            asio::ssl::stream<asio::ip::tcp::socket>,
            void*>;

private:
    // Store all informations on a request
    struct request_context {
        explicit request_context(asio::io_context& ioc) :
            timer(ioc)
        {
            response.body_limit(1024 * 1024 * 1024); // 1Go
        }
        asio::steady_timer      timer;
        bool                    too_late{false};

        beauty::request         request;
        beast::http::response_parser<beast::http::string_body> response;

        client::client_cb       cb;

        static
        std::shared_ptr<request_context> Create(asio::io_context& ioc, beauty::request&& req,
                const beauty::url& url, const beauty::duration& d, std::optional<client::client_cb> cb = {}) {

            // Create a request context to pass on each callback
            auto req_ctx = std::make_shared<request_context>(ioc);

            // Set up an HTTP GET request message
            req_ctx->request = std::move(req);
            req_ctx->request.version(11);
            req_ctx->request.target(std::string(url.path()) + std::string(url.query()));
            req_ctx->request.set(beast::http::field::host, url.host());
            req_ctx->request.set(beast::http::field::user_agent, BEAUTY_PROJECT_VERSION);
            req_ctx->request.prepare_payload();

            if (cb) {
                req_ctx->cb = std::move(*cb);
            }

            if (d.count()) {
                req_ctx->timer.expires_after(d);
            }

            return req_ctx;
        }
    };

public:
    template<bool U = SSL, typename std::enable_if_t<!U, int> = 0>
    explicit session_client(asio::io_context& ioc) :
            _ioc(ioc),
            _resolver(_ioc),
            _socket(_ioc),
#if   (BOOST_VERSION < 107000)
          _strand(_socket.get_executor())
#else
          _strand(asio::make_strand(ioc))
#endif
    {}

    template<bool U = SSL, typename std::enable_if_t<U, int> = 0>
    session_client(asio::io_context& ioc, asio::ssl::context& ctx) :
            _ioc(ioc),
            _resolver(_ioc),
            _socket(_ioc),
            _stream(ioc, ctx),
#if   (BOOST_VERSION < 107000)
          _strand(_socket.get_executor())
#else
          _strand(asio::make_strand(ioc))
#endif
    {}

    ~session_client() {
        // Gracefully close the socket
        boost::system::error_code ec;
        if constexpr(SSL) {
            _stream.shutdown(ec);
        }
        else {
            _socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
        }
    }

    void run(beauty::request&& req, const beauty::url& url, const beauty::duration& d)
    {
        // Create a request context to pass on each callback
        auto req_ctx = request_context::Create(_ioc, std::move(req), url, d);

        run(req_ctx, url);
    }

    // Start the asynchronous request
    void run(beauty::request&& req, const beauty::url& url, const beauty::duration& d,
            client::client_cb&& cb)
    {
        // Create a request context to pass on each callback
        auto req_ctx = request_context::Create(_ioc, std::move(req), url, d, std::move(cb));

        run(req_ctx, url);
    }

    // Start the asynchronous request
    void run(std::shared_ptr<request_context> req_ctx, const beauty::url& url)
    {
        if (req_ctx->timer.expiry() != asio::steady_timer::time_point()) {
            req_ctx->timer.async_wait(
                [me = this->shared_from_this(), req_ctx](const boost::system::error_code& ec) {
                    me->on_timer(ec, req_ctx);
                });
        }

        std::lock_guard guard{_requests_mtx};
        bool connection_required = false;
        if constexpr(SSL) {
            connection_required = (_requests.empty() && !_stream.next_layer().is_open());
        } else {
            connection_required = (_requests.empty() && !_socket.is_open());
        }
        //std::cout << "Start a request" << std::endl;
        _requests.push_back(req_ctx);

        if (connection_required) {
            //std::cout << "Try to resolve the host" << std::endl;

            // Set SNI Hostname (many hosts need this to handshake successfully)
            if constexpr(SSL) {
                std::string host{url.host()};
                if (!SSL_set_tlsext_host_name(_stream.native_handle(), host.c_str()))
                {
                    boost::system::error_code ec{static_cast<int>(::ERR_get_error()),
                            boost::asio::error::get_ssl_category()};
                    return fail(**_requests.begin(), ec, "set_tlsext_hostname");
                }
            }

            _pending_request = true;

            // Look up the domain name
            _resolver.async_resolve(
                url.host(),
                url.port_view(),
                [me = this->shared_from_this()](const boost::system::error_code& ec,
                        asio::ip::tcp::resolver::results_type results) {
                    me->on_resolve(ec, results);
                });
        }

        if (!_pending_request) {
            //std::cout << "should do something to rearm" << std::endl;
            do_write();
        } else {
            //std::cout << "nothing to do to rearm" << std::endl;
        }
    }

    void on_resolve(const boost::system::error_code& ec,
            asio::ip::tcp::resolver::results_type results)
    {
        //std::cout << "on resolve" << std::endl;
        if(ec) {
            std::lock_guard guard{_requests_mtx};
            return fail(**_requests.begin(), ec, "resolve");
        }

        // Make the connection on the IP address we get from a lookup
        if constexpr(SSL) {
            asio::async_connect(
                _stream.next_layer(),
                results.begin(),
                results.end(),
                [me = this->shared_from_this()](const boost::system::error_code& ec,
                        asio::ip::tcp::resolver::iterator it) {
                    me->on_connect(ec);
                }
            );
        }
        else {
            asio::async_connect(
                _socket,
                results.begin(),
                results.end(),
                [me = this->shared_from_this()](const boost::system::error_code& ec,
                        asio::ip::tcp::resolver::iterator it) {
                    me->on_connect(ec);
                }
            );
        }
    }

    void
    on_connect(const boost::system::error_code& ec)
    {
        //std::cout << "on connect" << std::endl;
        if(ec) {
            std::lock_guard guard{_requests_mtx};
            return fail(**_requests.begin(), ec, "connect");
        }

        if constexpr(SSL) {
            // Perform the SSL handshake
            _stream.async_handshake(
                asio::ssl::stream_base::client,
                [me = this->shared_from_this()](boost::system::error_code ec) {
                    me->on_handshake(ec);
                });
        }
        else {
            std::lock_guard guard{_requests_mtx};
            do_write();
        }
    }

    void
    on_handshake(boost::system::error_code ec) {
        if(ec) {
            std::lock_guard guard{_requests_mtx};
            return fail(**_requests.begin(), ec, "handshake");
        }

        std::lock_guard guard{_requests_mtx};
        do_write();
    }

    void
    do_write() {
        //std::cout << "do write" << std::endl;

        if (_requests.empty()) {
            //std::cout << " ... nothing to do" << std::endl;
            _pending_request = false;
            return;
        }

        auto req_ctx = *_requests.begin();
       _requests.pop_front();

       //std::cout << "start a write" << std::endl;
       _pending_request = true;

       // Send the HTTP request to the remote host
       if constexpr(SSL) {
           beast::http::async_write(_stream, req_ctx->request,
               asio::bind_executor(_strand,
                       [me = this->shared_from_this(), req_ctx](boost::system::error_code ec,
                               std::size_t bytes_transferred) {
                           me->on_write(ec, bytes_transferred, req_ctx);
                        })
            );
       }
       else {
           beast::http::async_write(_socket, req_ctx->request,
               asio::bind_executor(_strand,
                       [me = this->shared_from_this(), req_ctx](boost::system::error_code ec,
                               std::size_t bytes_transferred) {
                           me->on_write(ec, bytes_transferred, req_ctx);
                        })
            );
       }
    }

    void
    on_write(boost::system::error_code ec, std::size_t, std::shared_ptr<request_context> req_ctx)
    {
        //std::cout << "on write" << std::endl;
        if(ec) {
            return fail(*req_ctx, ec, "write");
        }

        // Receive the HTTP response
        if constexpr(SSL) {
            beast::http::async_read(_stream, _buffer, req_ctx->response,
                    asio::bind_executor(_strand,
                        [me = this->shared_from_this(), req_ctx](boost::system::error_code ec,
                                std::size_t bytes_transferred) {
                    me->on_read(ec, req_ctx);
                })
            );
        }
        else {
            beast::http::async_read(_socket, _buffer, req_ctx->response,
                    asio::bind_executor(_strand,
                        [me = this->shared_from_this(), req_ctx](boost::system::error_code ec,
                                std::size_t bytes_transferred) {
                    me->on_read(ec, req_ctx);
                })
            );
        }
    }

    void
    on_read(boost::system::error_code ec, std::shared_ptr<request_context> req_ctx)
    {
        //std::cout << "on read" << std::endl;
        if(ec) {
            return fail(*req_ctx, ec, "read");
        }

        req_ctx->timer.cancel(); // will call on_timer with operator_cancelled

        if (req_ctx->cb) {
            if (!req_ctx->too_late) {
                _response = req_ctx->response.release();
                req_ctx->cb(ec, std::move(_response));
            }
        } else {
            _response = req_ctx->response.release();
        }

        std::lock_guard guard{_requests_mtx};
        do_write();
    }

    void
    on_timer(boost::system::error_code ec, std::shared_ptr<request_context> req_ctx)
    {
        //std::cout << "on timer" << std::endl;
        if (!ec && !req_ctx->too_late) {
            fail(*req_ctx, boost::system::error_code(boost::system::errc::timed_out,
                    boost::system::system_category()),
                    "timeout");

            req_ctx->too_late = true;
        }
    }

    beauty::response& response() { return _response; }

private:
    asio::io_context&       _ioc;
    asio::ip::tcp::resolver _resolver;
    asio::ip::tcp::socket   _socket;
    stream_type                                   _stream = {};
    asio::strand<asio::io_context::executor_type> _strand;

    beast::flat_buffer      _buffer;

    // Synchronous response
    beauty::response        _response;

    // Asynchronous request - wait for connection
    std::mutex              _requests_mtx;
    std::deque<std::shared_ptr<request_context>> _requests;
    std::atomic_bool        _pending_request{false};

private:
    void fail(const request_context& req_ctx, boost::system::error_code ec, const char* /* msg not used */) {
        if (req_ctx.cb) {
            //std::cout << " !!! FAILED !!! " << ec << " with " << msg << std::endl;
            if (!req_ctx.too_late) {
                req_ctx.cb(ec, {});
            }
        } else {
            throw boost::system::system_error(ec);
        }
    }
};

}

max_stars_repo_name: Brian-Rader-Logikos/beauty

max_issues_repo_name: Brian-Rader-Logikos/beauty

max_forks_repo_name: Brian-Rader-Logikos/beauty


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

#include <mayaUsd/undo/UsdUndoBlock.h>
#include <mayaUsd/undo/UsdUndoManager.h>
#include <mayaUsd/undo/UsdUndoableItem.h>

#include <pxr/base/tf/pyContainerConversions.h>
#include <pxr/base/tf/pyNoticeWrapper.h>
#include <pxr/pxr.h>
#include <pxr/usd/sdf/layer.h>

#include <boost/python.hpp>

#include <memory>

using namespace boost::python;

PXR_NAMESPACE_USING_DIRECTIVE

namespace {
class PythonUndoBlock
{
public:
    PythonUndoBlock()
        : _block(nullptr)
    {
    }

    ~PythonUndoBlock() { }

    void enter()
    {
        if (!TF_VERIFY(_block == nullptr)) {
            return;
        }
        _block = std::make_unique<MayaUsd::UsdUndoBlock>();
    }

    void exit(object, object, object)
    {
        if (!TF_VERIFY(_block != nullptr)) {
            return;
        }
        _block.reset();
    }

private:
    std::unique_ptr<MayaUsd::UsdUndoBlock> _block;
};

void _trackLayerStates(const SdfLayerHandle& layer)
{
    MayaUsd::UsdUndoManager::instance().trackLayerStates(layer);
}

} // namespace

void wrapUsdUndoManager()
{
    // UsdUndoManager
    {
        typedef MayaUsd::UsdUndoManager This;
        class_<This, boost::noncopyable>("UsdUndoManager", no_init)
            .def("trackLayerStates", &_trackLayerStates)
            .staticmethod("trackLayerStates");
    }

    // UsdUndoBlock
    {
        typedef PythonUndoBlock This;
        class_<This, boost::noncopyable>("UsdUndoBlock", init<>())
            .def("__enter__", &This::enter)
            .def("__exit__", &This::exit);
    }
}

max_stars_repo_name: nguyenb-adsk/maya-usd

max_issues_repo_name: nguyenb-adsk/maya-usd

max_forks_repo_name: nguyenb-adsk/maya-usd


text:
#ifndef NULL_RAND_FLOWGRAPH_HPP
#define NULL_RAND_FLOWGRAPH_HPP

#include <gnuradio/top_block.h>
#include <sched/copy_rand.h>

#include <iostream>
#include <boost/program_options.hpp>

using namespace gr;

class null_rand_flowgraph {

private:
    size_t d_max_copy;
    int d_pipes;
    int d_stages;
    uint64_t d_samples;

public:
    null_rand_flowgraph(int pipes, int stages,
                   uint64_t samples, size_t max_copy);
	~null_rand_flowgraph();

	top_block_sptr tb;
    std::vector<sched::copy_rand::sptr> blocks;
};

#endif

max_stars_repo_name: LongHairedHacker/FutureSDR

max_issues_repo_name: BelmY/FutureSDR

max_forks_repo_name: BelmY/FutureSDR


text:
#ifndef ASLAM_TRANSFORMATION_EXPRESSION_NODE
#define ASLAM_TRANSFORMATION_EXPRESSION_NODE

#include <Eigen/Core>
#include <aslam/backend/JacobianContainer.hpp>
#include <boost/shared_ptr.hpp>
#include <set>

namespace aslam {
  namespace backend {
    class EuclideanExpression;
    class RotationExpression;
    class ExpressionNodeVisitor;

    class TransformationExpressionNode {
    public:
      TransformationExpressionNode();
      virtual ~TransformationExpressionNode();

      /// \brief Evaluate the transformation matrix.
      Eigen::Matrix4d evaluate() { return toTransformationMatrixImplementation(); }
      Eigen::Matrix4d toTransformationMatrix() { return toTransformationMatrixImplementation(); }

      /// \brief Evaluate the Jacobians
      void evaluateJacobians(JacobianContainer & outJacobians) const;
      template <typename DERIVED>
      EIGEN_ALWAYS_INLINE void evaluateJacobians(JacobianContainer & outJacobians, const Eigen::MatrixBase<DERIVED> & applyChainRule) const {
        evaluateJacobians(outJacobians.apply(applyChainRule));
      }
      void getDesignVariables(DesignVariable::set_t & designVariables) const;

      virtual void accept(ExpressionNodeVisitor& visitor); //TODO make pure and complete nodes
    protected:
      // These functions must be implemented by child classes.
      virtual Eigen::Matrix4d toTransformationMatrixImplementation() = 0;
      virtual void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const = 0;
      virtual void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const = 0;

      virtual RotationExpression toRotationExpression(const boost::shared_ptr<TransformationExpressionNode> & thisShared) const;
      virtual EuclideanExpression toEuclideanExpression(const boost::shared_ptr<TransformationExpressionNode> & thisShared) const;

      friend class TransformationExpression;
    };

    /**
     * \class TransformationExpressionNodeMultiply
     *
     * \brief A class representing the multiplication of two transformation matrices.
     *
     */
    class TransformationExpressionNodeMultiply : public TransformationExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      TransformationExpressionNodeMultiply(boost::shared_ptr<TransformationExpressionNode> lhs,
                                           boost::shared_ptr<TransformationExpressionNode> rhs);

      ~TransformationExpressionNodeMultiply() override;

      void accept(ExpressionNodeVisitor& visitor) override;
    private:
      Eigen::Matrix4d toTransformationMatrixImplementation() override;
      void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const override;
      void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const override;

      boost::shared_ptr<TransformationExpressionNode> _lhs;
      Eigen::Matrix4d _T_lhs;
      boost::shared_ptr<TransformationExpressionNode> _rhs;
      Eigen::Matrix4d _T_rhs;
    };

    /**
     * \class TransformationExpressionNodeInverse
     *
     * \brief A class representing the inverse of a transformation matrix.
     *
     */
    class TransformationExpressionNodeInverse : public TransformationExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      TransformationExpressionNodeInverse(boost::shared_ptr<TransformationExpressionNode> dvTransformation);

      ~TransformationExpressionNodeInverse() override;

      void accept(ExpressionNodeVisitor& visitor) override;
    private:
      Eigen::Matrix4d toTransformationMatrixImplementation() override;
      void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const override;
      void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const override;

      boost::shared_ptr<TransformationExpressionNode> _dvTransformation;
      Eigen::Matrix4d _T;
    };

    /**
     * \class TransformationExpressionNodeMultiply
     *
     * \brief A class representing the multiplication of two transformation matrices.
     *
     */
    class TransformationExpressionNodeConstant : public TransformationExpressionNode
    {
    public:
      EIGEN_MAKE_ALIGNED_OPERATOR_NEW

      TransformationExpressionNodeConstant(const Eigen::Matrix4d & T);
      ~TransformationExpressionNodeConstant() override;

      void accept(ExpressionNodeVisitor& visitor) override;
    private:
      Eigen::Matrix4d toTransformationMatrixImplementation() override;
      void evaluateJacobiansImplementation(JacobianContainer & outJacobians) const override;
      void getDesignVariablesImplementation(DesignVariable::set_t & designVariables) const override;

      Eigen::Matrix4d _T;
    };

  } // namespace backend
} // namespace aslam

#endif /* ASLAM_TRANSFORMATION_EXPRESSION_NODE */


text:
#include <Eigen/Core>

USING_PART_OF_NAMESPACE_EIGEN

using namespace std;

template<typename Scalar, typename Derived>
void foo(const MatrixBase<Scalar, Derived>& m)
{
  cout << "Here's m:" << endl << m << endl;
}

template<typename Scalar, typename Derived>
Eigen::ScalarMultiple<Derived>
twice(const MatrixBase<Scalar, Derived>& m)
{
  return 2 * m;
}

int main(int, char**)
{
  Matrix2d m = Matrix2d::random();
  foo(m);
  foo(twice(m));
  return 0;
}

max_stars_repo_name: Devaraj-G/volna

max_issues_repo_name: Devaraj-G/volna

max_forks_repo_name: Devaraj-G/volna


text:
#include "irep2.h"

#include <string.h>

#include <boost/static_assert.hpp>

#include <c_types.h>
#include <base_type.h>
#include <type_byte_size.h>
#include <limits.h>

expr2tc
expr2t::do_simplify(bool second __attribute__((unused))) const
{

  return expr2tc();
}

static const type2tc &
decide_on_expr_type(const expr2tc &side1, const expr2tc &side2)
{

  // For some arithmetic expr, decide on the result of operating on them.
  if (is_pointer_type(side1))
    return side1->type;
  if (is_pointer_type(side2))
    return side2->type;

  // Fixedbv's take precedence.
  if (is_fixedbv_type(side1))
    return side1->type;
  if (is_fixedbv_type(side2))
    return side2->type;

  // If one operand is bool, return the other, as that's either bool or will
  // have a higher rank.
  if (is_bool_type(side1))
    return side2->type;
  else if (is_bool_type(side2))
    return side1->type;

  assert(is_bv_type(side1) && is_bv_type(side2));

  unsigned int side1_width = side1->type->get_width();
  unsigned int side2_width = side2->type->get_width();

  if (side1->type == side2->type) {
    if (side1_width > side2_width)
      return side1->type;
    else
      return side2->type;
  }

  // Differing between signed/unsigned bv type. Take unsigned if greatest.
  if (is_unsignedbv_type(side1) && side1_width >= side2_width)
    return side1->type;

  if (is_unsignedbv_type(side2) && side2_width >= side1_width)
    return side2->type;

  // Otherwise return the signed one;
  if (is_signedbv_type(side1))
    return side1->type;
  else
    return side2->type;
}

static void
to_fixedbv(const expr2tc &op, fixedbvt &bv)
{

  // XXX XXX XXX -- this would appear to be broken in a couple of cases.
  // Take a look at the typecast cvt code -- where we're taking the target
  // type, fetching the fixedbv spec from that, and constructing from there.
  // Which turns out not to break test cases like 01_cbmc_Fixedbv8

  switch (op->expr_id) {
  case expr2t::constant_int_id:
    bv.spec = fixedbv_spect(128, 64); // XXX
    bv.from_integer(to_constant_int2t(op).constant_value);
    break;
  case expr2t::constant_bool_id:
    bv.spec = fixedbv_spect(32, 16); // XXX
    bv.from_integer((to_constant_bool2t(op).constant_value)
                     ? BigInt(1) : BigInt(0));
    break;
  case expr2t::constant_fixedbv_id:
    bv = to_constant_fixedbv2t(op).value;
    break;
  default:
    assert(0 && "Unexpectedly typed argument to to_fixedbv");
  }
}

static expr2tc
from_fixedbv(const fixedbvt &bv, const type2tc &type)
{

  switch (type->type_id) {
  case type2t::bool_id:
    {
    bool theval = bv.is_zero() ? false : true;
    return expr2tc(new constant_bool2t(theval));
    }
  case type2t::unsignedbv_id:
  case type2t::signedbv_id:
    {
    // To integer truncates non-integer bits, it turns out.
    BigInt tmp = bv.to_integer();

    // Round away upper bits, just in case we're decreasing accuracy here.
    unsigned int bits = type->get_width();
    fixedbvt tmp_bv;
    tmp_bv.spec = bv.spec;
    tmp_bv.from_integer(tmp);
    tmp_bv.round(fixedbv_spect(bits*2, bits));

    // If we're converting to a signedbv, the top bit being set means negative.
    if (is_signedbv_type(type) && !tmp.is_negative()) {
      assert(type->get_width() <= 64);
      uint64_t top_bit = 1ULL << (type->get_width()-1);
      uint64_t cur_val = tmp_bv.to_integer().to_uint64();
      if (cur_val >= top_bit) {
        // Construct some bit mask gumpf as a sign extension
        int64_t large_int = -1;
        large_int <<= (type->get_width() - 1);
        large_int |= cur_val;
        tmp_bv.from_integer(large_int);
      }
    } else if (is_signedbv_type(type)) {
      int64_t theval = tmp.to_int64();
      tmp_bv.from_integer(theval);
    } else if (is_unsignedbv_type(type) && tmp_bv.to_integer().is_negative()) {
      // Need to switch this number to being an unsigned representation of the
      // same bit vector.
      int64_t the_num = tmp_bv.to_integer().to_int64();

      unsigned int width = type->get_width();
      uint64_t mask = (1ULL << width) - 1ULL;
      if (width == 64)
        mask = 0xFFFFFFFFFFFFFFFF;

      uint64_t output = the_num & mask;
      tmp_bv.from_integer(BigInt(output));
    }

    // And done.
    return expr2tc(new constant_int2t(type, tmp_bv.to_integer()));
    }
  case type2t::fixedbv_id:
    return expr2tc(new constant_fixedbv2t(type, bv));
  default:
    std::cerr << "Unexpected typed argument to from_fixedbv" << std::endl;
    abort();
  }
}

void
make_fixedbv_types_match(fixedbvt &bv1, fixedbvt &bv2)
{

  // First, simple case,
  if (bv1.spec.width == bv2.spec.width &&
      bv1.spec.integer_bits == bv2.spec.integer_bits)
    return;

  // Otherwise, pick the large one, assuming we're always keeping the int/frac
  // division at the middle,
  if (bv1.spec.width > bv2.spec.width)
    bv2.round(bv1.spec);
  else
    bv1.round(bv2.spec);

  return;
}

static void
fetch_ops_from_this_type(std::list<expr2tc> &ops, expr2t::expr_ids id,
                         const expr2tc &expr)
{

  if (expr->expr_id == id) {
    expr->foreach_operand([&ops, id] (const expr2tc &e) {
      fetch_ops_from_this_type(ops, id, e);
      }
    );
  } else {
    ops.push_back(expr);
  }
}

static bool
rebalance_associative_tree(const expr2t &expr, std::list<expr2tc> &ops,
        expr2tc (*create_obj_wrapper)(const expr2tc &arg1, const expr2tc &arg2))
{

  // So the purpose of this is to take a tree of all-the-same-operation and
  // re-arrange it so that there are some operations that we can simplify.
  // In old irep things like addition or subtraction or whatever could take
  // a whole set of operands (however many you shoved in the vector) and those
  // could all be simplified with each other. However, now that we've moved to
  // binary-only ireps, this isn't possible (and it's causing high
  // inefficiencies).
  // So instead, reconstruct a tree of all-the-same ireps into a vector and
  // try to simplify all of their contents, then try to reconfigure into another
  // set of operations.
  // There's great scope for making this /much/ more efficient via passing modes
  // and vectors downwards, but lets not prematurely optimise. All this is
  // faster than stringly stuff.

  // Extract immediate operands
  expr.foreach_operand([&ops, &expr] (const expr2tc &e) {
      fetch_ops_from_this_type(ops, expr.expr_id, e);
    }
  );

  // Are there enough constant values in there?
  unsigned int const_values = 0;
  unsigned int orig_size = ops.size();
  for (std::list<expr2tc>::const_iterator it = ops.begin();
       it != ops.end(); it++)
    if (is_constant_expr(*it))
      const_values++;

  // Nothing for us to simplify.
  if (const_values <= 1)
    return false;

  // Otherwise, we can go through simplifying operands.
  expr2tc accuml;
  for (std::list<expr2tc>::iterator it = ops.begin();
       it != ops.end(); it++) {
    if (!is_constant_expr(*it))
      continue;

    // We have a constant; do we have another constant to simplify with?
    if (is_nil_expr(accuml)) {
      // Juggle iterators, our iterator becomes invalid when we erase it.
      std::list<expr2tc>::iterator back = it;
      back--;
      accuml = *it;
      ops.erase(it);
      it = back;
      continue;
    }

    // Now attempt to simplify that. Create a new associative object and
    // give it a shot.
    expr2tc tmp = create_obj_wrapper(accuml, *it);
    if (is_nil_expr(tmp))
      continue; // Creating wrapper rejected it.

    tmp = tmp->simplify();
    if (is_nil_expr(tmp))
      // For whatever reason we're unable to simplify these two constants.
      continue;

    // It's good; remove that object from the list.
    accuml = tmp;
    std::list<expr2tc>::iterator back = it;
    back--;
    ops.erase(it);
    it = back;
  }

  // So, we've attempted to remove some things. There are three cases.
  // First, nothing was pulled out of the list. Shouldn't happen, but just
  // in case...
  if (ops.size() == orig_size)
    return false;

  // If only one constant value was removed from the list, then we attempted to
  // simplify two constants and it failed. No simplification.
  if (ops.size() == orig_size - 1)
    return false;

  // Finally; we've succeeded and simplified something. Push the simplified
  // constant back at the end of the list.
  ops.push_back(accuml);
  return true;
}

expr2tc
attempt_associative_simplify(const expr2t &expr,
        expr2tc (*create_obj_wrapper)(const expr2tc &arg1, const expr2tc &arg2))
{

  std::list<expr2tc> operands;
  if (rebalance_associative_tree(expr, operands, create_obj_wrapper)) {
    // Horray, we simplified. Recreate.
    assert(operands.size() >= 2);
    std::list<expr2tc>::const_iterator it = operands.begin();
    expr2tc accuml = *it;
    it++;
    for ( ; it != operands.end(); it++) {
      expr2tc tmp;
      accuml = create_obj_wrapper(accuml, *it);
      if (is_nil_expr(accuml))
        return expr2tc(); // wrapper rejected new obj :O
    }

    return accuml;
  } else {
    return expr2tc();
  }
}

static expr2tc
create_add_wrapper(const expr2tc &arg1, const expr2tc &arg2)
{

  const type2tc &type = decide_on_expr_type(arg1, arg2);
  return expr2tc(new add2t(type, arg1, arg2));
}

expr2tc
add2t::do_simplify(bool second) const
{

  if (!is_constant_expr(side_1) || !is_constant_expr(side_2)) {
    if (!second)
      // Wait until operands are simplified
      return expr2tc();

    // If one is zero, return the other.
    if (is_constant_expr(side_1)) {
      fixedbvt op;
      to_fixedbv(side_1, op);
      if (op.is_zero())
        return side_2;
    }

    if (is_constant_expr(side_2)) {
      fixedbvt op;
      to_fixedbv(side_2, op);
      if (op.is_zero())
        return side_1;
    }

    // Attempt to simplify associative tree.
    return attempt_associative_simplify(*this, create_add_wrapper);
  }

  assert((is_constant_int2t(side_1) || is_constant_bool2t(side_1) ||
          is_constant_fixedbv2t(side_1)) &&
         (is_constant_int2t(side_2) || is_constant_bool2t(side_2) ||
          is_constant_fixedbv2t(side_2)) &&
          "Operands to simplified add must be int, bool or fixedbv");

  // The plan: convert everything to a fixedbv, operate, and convert back to
  // whatever form we need. Fixedbv appears to be a wrapper around BigInt.
  fixedbvt operand1, operand2;
  to_fixedbv(side_1, operand1);
  to_fixedbv(side_2, operand2);

  make_fixedbv_types_match(operand1, operand2);
  operand1 += operand2;

  return from_fixedbv(operand1, type);
}

expr2tc
sub2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_expr(side_1) || !is_constant_expr(side_2))
    return expr2tc();

  assert((is_constant_int2t(side_1) || is_constant_bool2t(side_1) ||
          is_constant_fixedbv2t(side_1)) &&
         (is_constant_int2t(side_2) || is_constant_bool2t(side_2) ||
          is_constant_fixedbv2t(side_2)) &&
          "Operands to simplified sub must be int, bool or fixedbv");

  fixedbvt operand1, operand2;
  to_fixedbv(side_1, operand1);
  to_fixedbv(side_2, operand2);

  make_fixedbv_types_match(operand1, operand2);
  operand1 -= operand2;

  return from_fixedbv(operand1, type);
}

static expr2tc
mul_check_for_zero_or_one(const expr2tc &checking, const expr2tc &other_op,
                          const type2tc &ourtype)
{

  fixedbvt operand;
  to_fixedbv(checking, operand);

  if (operand.is_zero())
    return from_fixedbv(operand, ourtype); // Mul by zero -> return zero

  fixedbvt one = operand;
  one.from_integer(BigInt(1));
  if (operand == one) { // Mul by one -> return other operand.
    if (other_op->type == ourtype)
      return other_op;
    else
      return expr2tc(new typecast2t(ourtype, other_op));
  }

  // Return nothing, nothing to simplify.
  return expr2tc();
}

expr2tc
mul2t::do_simplify(bool second __attribute__((unused))) const
{

  // If we don't have two constant operands, check for one being zero.
  if (!is_constant_expr(side_1) || !is_constant_expr(side_2)) {
    if (is_constant_expr(side_1)) {
      expr2tc tmp = mul_check_for_zero_or_one(side_1, side_2, type);
      if (!is_nil_expr(tmp))
        return tmp;
    }

    if (is_constant_expr(side_2)) {
      expr2tc tmp = mul_check_for_zero_or_one(side_2, side_1, type);
      if (!is_nil_expr(tmp))
        return tmp;
    }

    return expr2tc();
  }

  assert((is_constant_int2t(side_1) || is_constant_bool2t(side_1) ||
          is_constant_fixedbv2t(side_1)) &&
         (is_constant_int2t(side_2) || is_constant_bool2t(side_2) ||
          is_constant_fixedbv2t(side_2)) &&
          "Operands to simplified mul must be int, bool or fixedbv");

  fixedbvt operand1, operand2;
  to_fixedbv(side_1, operand1);
  to_fixedbv(side_2, operand2);

  // Multiplication by any zero operand -> zero
  if (operand1.is_zero())
    return from_fixedbv(operand1, type);
  if (operand2.is_zero())
    return from_fixedbv(operand2, type);

  make_fixedbv_types_match(operand1, operand2);
  operand1 *= operand2;

  return from_fixedbv(operand1, type);
}

expr2tc
div2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_expr(side_1) || !is_constant_expr(side_2)) {
    // If side_1 is zero, result is zero.
    if (is_constant_expr(side_1)) {
      fixedbvt operand1;
      to_fixedbv(side_1, operand1);
      if (operand1.is_zero())
        return from_fixedbv(operand1, type);
      else
        return expr2tc();
    } else {
      return expr2tc();
    }
  }

  assert((is_constant_int2t(side_1) || is_constant_bool2t(side_1) ||
          is_constant_fixedbv2t(side_1)) &&
         (is_constant_int2t(side_2) || is_constant_bool2t(side_2) ||
          is_constant_fixedbv2t(side_2)) &&
          "Operands to simplified div must be int, bool or fixedbv");

  fixedbvt operand1, operand2;
  to_fixedbv(side_1, operand1);
  to_fixedbv(side_2, operand2);

  if (operand1.is_zero())
    return from_fixedbv(operand1, type);

  // Div by zero -> not allowed. XXX - this should never reach this point, but
  // if it does, perhaps the caller has some nondet guard that guarentees it's
  // never evaluated. Either way, don't explode, just refuse to simplify.
  if (operand2.is_zero())
    return expr2tc();

  make_fixedbv_types_match(operand1, operand2);
  operand1 /= operand2;

  return from_fixedbv(operand1, type);
}

expr2tc
modulus2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_expr(side_1) || !is_constant_expr(side_2))
    return expr2tc();

  assert((is_constant_int2t(side_1) || is_constant_bool2t(side_1) ||
          is_constant_fixedbv2t(side_1)) &&
         (is_constant_int2t(side_2) || is_constant_bool2t(side_2) ||
          is_constant_fixedbv2t(side_2)) &&
          "Operands to simplified div must be int, bool or fixedbv");

  fixedbvt operand1, operand2;
  to_fixedbv(side_1, operand1);
  to_fixedbv(side_2, operand2);

  make_fixedbv_types_match(operand1, operand2);
  fixedbvt quotient = operand1;
  quotient /= operand2; // calculate quotient.
  // Truncate fraction bits.
  quotient.from_integer(quotient.to_integer());
  quotient *= operand2; // to subtract.
  operand1 -= quotient; // And finally, the remainder.

  return from_fixedbv(operand1, type);
}

expr2tc
neg2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_expr(value))
    return expr2tc();

  assert((is_constant_int2t(value) || is_constant_bool2t(value) ||
          is_constant_fixedbv2t(value)) &&
          "Operands to simplified neg2t must be int, bool or fixedbv");

  // The plan: convert everything to a fixedbv, operate, and convert back to
  // whatever form we need. Fixedbv appears to be a wrapper around BigInt.
  fixedbvt operand;
  to_fixedbv(value, operand);

  operand.negate();

  return from_fixedbv(operand, type);
}

expr2tc
with2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_struct2t(source_value)) {
    const constant_struct2t &c_struct = to_constant_struct2t(source_value);
    const constant_string2t &memb = to_constant_string2t(update_field);
    unsigned no = static_cast<const struct_union_data&>(*type.get())
                  .get_component_number(memb.value);
    assert(no < c_struct.datatype_members.size());

    // Clone constant struct, update its field according to this "with".
    constant_struct2tc s = expr2tc(c_struct.clone());
    s.get()->datatype_members[no] = update_value;
    return expr2tc(s);
  } else if (is_constant_union2t(source_value)) {
    const constant_union2t &c_union = to_constant_union2t(source_value);
    const union_type2t &thetype = to_union_type(c_union.type);
    const constant_string2t &memb = to_constant_string2t(update_field);
    unsigned no = static_cast<const struct_union_data&>(*c_union.type.get())
                  .get_component_number(memb.value);
    assert(no < thetype.member_names.size());

    // If the update value type matches the current lump of data's type, we can
    // just replace it with the new value. As far as I can tell, constant unions
    // only ever contain one member, and it's the member most recently written.
    if (thetype.members[no] != update_value->type)
      return expr2tc();

    std::vector<expr2tc> newmembers;
    newmembers.push_back(update_value);
    return expr2tc(new constant_union2t(type, newmembers));
  } else if (is_constant_array2t(source_value) &&
             is_constant_int2t(update_field)) {
    const constant_array2t &array = to_constant_array2t(source_value);
    const constant_int2t &index = to_constant_int2t(update_field);

    // Index may be out of bounds. That's an error in the program, but not in
    // the model we're generating, so permit it. Can't simplify it though.
    if (index.as_ulong() >= array.datatype_members.size())
      return expr2tc();

    constant_array2tc arr = expr2tc(array.clone());
    arr.get()->datatype_members[index.as_ulong()] = update_value;
    return expr2tc(arr);
  } else if (is_constant_array_of2t(source_value)) {
    const constant_array_of2t &array = to_constant_array_of2t(source_value);

    // We don't simplify away these withs if // the array_of is infinitely
    // sized. This is because infinitely sized arrays are no longer converted
    // correctly in the solver backend (they're simply not supported by SMT).
    // Thus it becomes important to be able to assign a value to a field in an
    // aray_of and not have it const propagatated away.
    const constant_array_of2t &thearray = to_constant_array_of2t(source_value);
    const array_type2t &arr_type = to_array_type(thearray.type);
    if (arr_type.size_is_infinite)
      return expr2tc();

    // We can eliminate this operation if the operand to this with is the same
    // as the initializer.
    if (update_value == array.initializer)
      return source_value;
    else
      return expr2tc();
  } else {
    return expr2tc();
  }
}

expr2tc
member2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_struct2t(source_value) || is_constant_union2t(source_value)) {
    unsigned no =
      static_cast<const struct_union_data&>(*source_value->type.get())
      .get_component_number(member);

    // Clone constant struct, update its field according to this "with".
    expr2tc s;
    if (is_constant_struct2t(source_value)) {
      s = to_constant_struct2t(source_value).datatype_members[no];

      assert(is_pointer_type(type) ||
             base_type_eq(type, s->type, namespacet(contextt())));
    } else {
      // The constant array has some number of elements, up to the size of the
      // array, but possibly fewer. This is legal C. So bounds check first that
      // we can actually perform this member operation.
      const constant_union2t &uni = to_constant_union2t(source_value);
      if (uni.datatype_members.size() <= no)
        return expr2tc();

      s = uni.datatype_members[no];

      // If the type we just selected isn't compatible, it means that whatever
      // field is in the constant union /isn't/ the field we're selecting from
      // it. So don't simplify it, because we can't.
      if (!is_pointer_type(type) &&
          !base_type_eq(type, s->type, namespacet(contextt())))
        return expr2tc();
    }

    return s;
  } else {
    return expr2tc();
  }
}

expr2tc
pointer_offs_simplify_2(const expr2tc &offs, const type2tc &type)
{

  if (is_symbol2t(offs) || is_constant_string2t(offs)) {
    return expr2tc(new constant_int2t(type, BigInt(0)));
  } else if (is_index2t(offs)) {
    const index2t &index = to_index2t(offs);

    if (is_symbol2t(index.source_value) && is_constant_int2t(index.index)) {
      // We can reduce to that index offset.
      const array_type2t &arr = to_array_type(index.source_value->type);
      unsigned int widthbits = arr.subtype->get_width();
      unsigned int widthbytes = widthbits / 8;
      BigInt val = to_constant_int2t(index.index).constant_value;
      val *= widthbytes;
      return expr2tc(new constant_int2t(type, val));
    } else if (is_constant_string2t(index.source_value) &&
               is_constant_int2t(index.index)) {
      // This can also be simplified to an array offset. Just return the index,
      // as the string elements are all 8 bit bytes.
      return index.index;
    } else {
      return expr2tc();
    }
  } else {
    return expr2tc();
  }
}

expr2tc
pointer_offset2t::do_simplify(bool second) const
{

  // XXX - this could be better. But the current implementation catches most
  // cases that ESBMC produces internally.

  if (second && is_address_of2t(ptr_obj)) {
    const address_of2t &addrof = to_address_of2t(ptr_obj);
    return pointer_offs_simplify_2(addrof.ptr_obj, type);
  } else if (is_typecast2t(ptr_obj)) {
    const typecast2t &cast = to_typecast2t(ptr_obj);
    expr2tc new_ptr_offs = expr2tc(new pointer_offset2t(type, cast.from));
    expr2tc reduced = new_ptr_offs->simplify();

    // No good simplification -> return nothing
    if (is_nil_expr(reduced))
      return reduced;

    // If it simplified to zero, that's fine, return that.
    if (is_constant_int2t(reduced) &&
        to_constant_int2t(reduced).constant_value.is_zero())
      return reduced;

    // If it didn't reduce to zero, give up. Not sure why this is the case,
    // but it's what the old irep code does.
    return expr2tc();
  } else if (is_add2t(ptr_obj)) {
    const add2t &add = to_add2t(ptr_obj);

    // So, one of these should be a ptr type, or there isn't any point in this
    // being a pointer_offset irep.
    if (!is_pointer_type(add.side_1) &&
        !is_pointer_type(add.side_2))
      return expr2tc();

    // Can't have pointer-on-pointer arith.
    assert(!(is_pointer_type(add.side_1) &&
             is_pointer_type(add.side_2)));

    expr2tc ptr_op = (is_pointer_type(add.side_1)) ? add.side_1 : add.side_2;
    expr2tc non_ptr_op =
      (is_pointer_type(add.side_1)) ? add.side_2 : add.side_1;

    // Can't do any kind of simplification if the ptr op has a symbolic type.
    // Let the SMT layer handle this. In the future, can we pass around a
    // namespace?
    if (is_symbol_type(to_pointer_type(ptr_op->type).subtype))
      return expr2tc();

    // Turn the pointer one into pointer_offset.
    expr2tc new_ptr_op = expr2tc(new pointer_offset2t(type, ptr_op));
    // And multiply the non pointer one by the type size.
    type2tc ptr_int_type = get_int_type(config.ansi_c.pointer_width);
    type2tc ptr_subtype = to_pointer_type(ptr_op->type).subtype;
    mp_integer thesize = (is_empty_type(ptr_subtype)) ? 1
                          : type_byte_size(*ptr_subtype.get());
    constant_int2tc type_size(type, thesize);

    // SV-Comp workaround
    if (non_ptr_op->type->get_width() != type->get_width())
      non_ptr_op = typecast2tc(type, non_ptr_op);

    mul2tc new_non_ptr_op(type, non_ptr_op, type_size);

    expr2tc new_add = expr2tc(new add2t(type, new_ptr_op, new_non_ptr_op));

    // So, this add is a valid simplification. We may be able to simplify
    // further though.
    expr2tc tmp = new_add->simplify();
    if (is_nil_expr(tmp))
      return new_add;
    else
      return tmp;
  } else {
    return expr2tc();
  }
}

expr2tc
index2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_with2t(source_value)) {
    if (index == to_with2t(source_value).update_field) {
      // Index is the same as an update to the thing we're indexing; we can
      // just take the update value from the "with" below.
      return to_with2t(source_value).update_value;
    }

    return expr2tc();
  } else if (is_constant_array2t(source_value) && is_constant_int2t(index)) {
    const constant_array2t &arr = to_constant_array2t(source_value);
    const constant_int2t &idx = to_constant_int2t(index);

    // Index might be greater than the constant array size. This means we can't
    // simplify it, and the user might be eaten by an assertion failure in the
    // model. We don't have to think about this now though.
    if (idx.constant_value.is_negative())
      return expr2tc();

    unsigned long the_idx = idx.as_ulong();
    if (the_idx >= arr.datatype_members.size())
      return expr2tc();

    return arr.datatype_members[the_idx];
  } else if (is_constant_string2t(source_value) && is_constant_int2t(index)) {
    const constant_string2t &str = to_constant_string2t(source_value);
    const constant_int2t &idx = to_constant_int2t(index);

    // Same index situation
    unsigned long the_idx = idx.as_ulong();
    if (the_idx > str.value.as_string().size()) // allow reading null term.
      return expr2tc();

    // String constants had better be some kind of integer type
    assert(is_bv_type(type));
    unsigned long val = str.value.as_string().c_str()[the_idx];
    return expr2tc(new constant_int2t(type, BigInt(val)));
  } else if (is_constant_array_of2t(source_value)) {
    // Only thing this index can evaluate to is the default value of this array
    return to_constant_array_of2t(source_value).initializer;
  } else {
    return expr2tc();
  }
}

expr2tc
not2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_not2t(value))
    // These negate.
    return to_not2t(value).value;

  if (!is_constant_bool2t(value))
    return expr2tc();

  const constant_bool2t &val = to_constant_bool2t(value);
  return expr2tc(new constant_bool2t(!val.constant_value));
}

expr2tc
and2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_bool2t(side_1)) {
   if (to_constant_bool2t(side_1).constant_value)
     // constant true; other operand determines truth
     return side_2;
   else
     // constant false; never true.
     return side_1;
  }

  if (is_constant_bool2t(side_2)) {
   if (to_constant_bool2t(side_2).constant_value)
     // constant true; other operand determines truth
     return side_1;
   else
     // constant false; never true.
     return side_2;
  }

  if (!is_constant_bool2t(side_1) || !is_constant_bool2t(side_2))
    return expr2tc();

  const constant_bool2t &val1 = to_constant_bool2t(side_1);
  const constant_bool2t &val2 = to_constant_bool2t(side_2);
  return expr2tc(new constant_bool2t(val1.constant_value &&
                                     val2.constant_value));
}

expr2tc
or2t::do_simplify(bool second __attribute__((unused))) const
{

  // If either operand is true, the expr is true
  if (is_constant_bool2t(side_1) && to_constant_bool2t(side_1).constant_value)
    return true_expr;

  if (is_constant_bool2t(side_2) && to_constant_bool2t(side_2).constant_value)
    return true_expr;

  // If both or operands are false, the expr is false.
  if (is_constant_bool2t(side_1)
      && !to_constant_bool2t(side_1).constant_value
      && is_constant_bool2t(side_2)
      && !to_constant_bool2t(side_2).constant_value)
    return false_expr;

  return expr2tc();
}

expr2tc
xor2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_bool2t(side_1) || !is_constant_bool2t(side_2))
    return expr2tc();

  const constant_bool2t &val1 = to_constant_bool2t(side_1);
  const constant_bool2t &val2 = to_constant_bool2t(side_2);
  return expr2tc(new constant_bool2t(val1.constant_value ^
                                     val2.constant_value));
}

expr2tc
implies2t::do_simplify(bool second __attribute__((unused))) const
{

  // False => * evaluate to true, always
  if (is_constant_bool2t(side_1) && !to_constant_bool2t(side_1).constant_value)
    return true_expr;

  // Otherwise, the only other thing that will make this expr always true is
  // if side 2 is true.
  if (is_constant_bool2t(side_2) && to_constant_bool2t(side_2).constant_value)
    return true_expr;

  return expr2tc();
}

static expr2tc
do_bit_munge_operation(int64_t (*opfunc)(int64_t, int64_t),
                       const type2tc &type, const expr2tc &side_1,
                       const expr2tc &side_2)
{
  int64_t val1, val2;

  // Only support integer and's. If you're a float, pointer, or whatever, you're
  // on your own.
  if (!is_constant_int2t(side_1) || !is_constant_int2t(side_2))
    return expr2tc();

  // So - we can't make BigInt by itself do an and operation. But we can dump
  // it to a binary representation, and then and that.
  const constant_int2t &int1 = to_constant_int2t(side_1);
  const constant_int2t &int2 = to_constant_int2t(side_2);

  // Drama: BigInt does *not* do any kind of twos compliment representation.
  // In fact, negative numbers are stored as positive integers, but marked as
  // being negative. To get around this, perform operations in an {u,}int64,
  if (int1.constant_value.get_len() * sizeof(BigInt::onedig_t)
                                         > sizeof(int64_t) ||
      int2.constant_value.get_len() * sizeof(BigInt::onedig_t)
                                           > sizeof(int64_t))
    return expr2tc();

  // Dump will zero-prefix and right align the output number.
  val1 = int1.constant_value.to_int64();
  val2 = int2.constant_value.to_int64();

  if (int1.constant_value.is_negative()) {
    if (val1 & 0x8000000000000000ULL) {
      // Too large to fit, negative, in an int64_t.
      return expr2tc();
    } else {
      val1 = -val1;
    }
  }

  if (int2.constant_value.is_negative()) {
    if (val2 & 0x8000000000000000ULL) {
      // Too large to fit, negative, in an int64_t.
      return expr2tc();
    } else {
      val2 = -val2;
    }
  }

  val1 = opfunc(val1, val2);

  // This has potentially become negative. Check the top bit.
  if (val1 & (1 << (type->get_width() - 1)) && is_signedbv_type(type)) {
    // Sign extend.
    val1 |= ULLONG_MAX << (type->get_width());
  }

  // And now, restore, paying attention to whether this is supposed to be
  // signed or not.
  constant_int2t *theint;
  if (is_signedbv_type(type))
    theint = new constant_int2t(type, BigInt(val1));
  else
    theint = new constant_int2t(type, BigInt((uint64_t)val1));

  return expr2tc(theint);
}

static int64_t
do_bitand_op(int64_t op1, int64_t op2)
{
  return op1 & op2;
}

expr2tc
bitand2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitand_op, type, side_1, side_2);
}

static int64_t
do_bitor_op(int64_t op1, int64_t op2)
{
  return op1 | op2;
}

expr2tc
bitor2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitor_op, type, side_1, side_2);
}

static int64_t
do_bitxor_op(int64_t op1, int64_t op2)
{
  return op1 ^ op2;
}

expr2tc
bitxor2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitxor_op, type, side_1, side_2);
}

static int64_t
do_bitnand_op(int64_t op1, int64_t op2)
{
  return ~(op1 & op2);
}

expr2tc
bitnand2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitnand_op, type, side_1, side_2);
}

static int64_t
do_bitnor_op(int64_t op1, int64_t op2)
{
  return ~(op1 | op2);
}

expr2tc
bitnor2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitnor_op, type, side_1, side_2);
}

static int64_t
do_bitnxor_op(int64_t op1, int64_t op2)
{
  return ~(op1 ^ op2);
}

expr2tc
bitnxor2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitnxor_op, type, side_1, side_2);
}

static int64_t
do_bitnot_op(int64_t op1, int64_t op2 __attribute__((unused)))
{
  return ~op1;
}

expr2tc
bitnot2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_bitnot_op, type, value, value);
}

static int64_t
do_shl_op(int64_t op1, int64_t op2)
{
  return op1 << op2;
}

expr2tc
shl2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_shl_op, type, side_1, side_2);
}

static int64_t
do_lshr_op(int64_t op1, int64_t op2)
{
  return ((uint64_t)op1) >> ((uint64_t)op2);
}

expr2tc
lshr2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_lshr_op, type, side_1, side_2);
}

static int64_t
do_ashr_op(int64_t op1, int64_t op2)
{
  return op1 >> op2;
}

expr2tc
ashr2t::do_simplify(bool second __attribute__((unused))) const
{
  return do_bit_munge_operation(do_ashr_op, type, side_1, side_2);
}

expr2tc
typecast2t::do_simplify(bool second) const
{

  // Follow approach of old irep, i.e., copy it
  if (type == from->type) {
    // Typecast to same type means this can be eliminated entirely
    return from;
  } else if (is_bool_type(type)) {
    // Bool type -> turn into equality with zero
    expr2tc zero;
    if (is_pointer_type(from)) {
      zero = expr2tc(new symbol2t(from->type, irep_idt("NULL")));
    } else {
      fixedbvt bv;
      bv.from_integer(BigInt(0));
      zero = from_fixedbv(bv, from->type);
    }
    expr2tc eq = expr2tc(new equality2t(from, zero));
    expr2tc noteq = expr2tc(new not2t(eq));
    return noteq;
  } else if (is_symbol2t(from) && to_symbol2t(from).thename == "NULL"
             && is_pointer_type(type)){
    // Casts of null can operate on null directly. So long as we're casting it
    // to a pointer. Code like 32_floppy casts it to an int though; were we to
    // simplify that away, we end up with type errors.
    return from;
  } else if (is_pointer_type(type) && is_pointer_type(from)) {
    // Casting from one pointer to another is meaningless... except when there's
    // pointer arithmetic about to be applied to it. So, only remove typecasts
    // that don't change the subtype width.
    const pointer_type2t &ptr_to = to_pointer_type(type);
    const pointer_type2t &ptr_from = to_pointer_type(from->type);

    if (is_symbol_type(ptr_to.subtype) || is_symbol_type(ptr_from.subtype) ||
        is_code_type(ptr_to.subtype) || is_code_type(ptr_from.subtype))
      return expr2tc(); // Not worth thinking about

    if (is_array_type(ptr_to.subtype) &&
        is_symbol_type(get_array_subtype(ptr_to.subtype)))
      return expr2tc(); // Not worth thinking about

    if (is_array_type(ptr_from.subtype) &&
        is_symbol_type(get_array_subtype(ptr_from.subtype)))
      return expr2tc(); // Not worth thinking about

    try {
      unsigned int to_width = (is_empty_type(ptr_to.subtype)) ? 8
                              : ptr_to.subtype->get_width();
      unsigned int from_width = (is_empty_type(ptr_from.subtype)) ? 8
                              : ptr_from.subtype->get_width();

      if (to_width == from_width)
        return from;
      else
        return expr2tc();
    } catch (array_type2t::dyn_sized_array_excp*e) {
      // Something crazy, and probably C++ based, occurred. Don't attempt to
      // simplify.
      return expr2tc();
    }
  } else if (is_constant_expr(from)) {
    // Casts from constant operands can be done here.
    if (is_constant_bool2t(from) && is_bv_type(type)) {
      if (to_constant_bool2t(from).constant_value) {
        return expr2tc(new constant_int2t(type, BigInt(1)));
      } else {
        return expr2tc(new constant_int2t(type, BigInt(0)));
      }
    } else if (is_bool_type(type) && (is_constant_int2t(from) ||
                                      is_constant_fixedbv2t(from))) {
      fixedbvt bv;
      to_fixedbv(from, bv);
      if (bv.get_value().is_zero()) {
        return false_expr;
      } else {
        return true_expr;
      }
    } else if (is_bv_type(from) && is_fixedbv_type(type)) {
      fixedbvt f;
      f.spec = to_fixedbv_type(migrate_type_back(type)); // Dodgy.
      f.from_integer(to_constant_int2t(from).constant_value);
      exprt ref = f.to_expr();
      expr2tc cvt;
      migrate_expr(ref, cvt);
      return cvt;
    } else if (is_fixedbv_type(from) && is_fixedbv_type(type)) {
      fixedbvt f(to_constant_fixedbv2t(from).value);
      f.round(to_fixedbv_type(migrate_type_back(type)));
      exprt ref = f.to_expr();
      expr2tc cvt;
      migrate_expr(ref, cvt);
      return cvt;
    } else if ((is_bv_type(type) || is_fixedbv_type(type)) &&
                (is_bv_type(from) || is_fixedbv_type(from))) {
      fixedbvt bv;
      to_fixedbv(from, bv);
      return from_fixedbv(bv, type);
    } else {
      return expr2tc();
    }
  } else if (is_typecast2t(from) && type == from->type) {
    // Typecast from a typecast can be eliminated. We'll be simplified even
    // further by the caller.
    return expr2tc(new typecast2t(type, to_typecast2t(from).from));
  } else if (second && is_bv_type(type) && is_bv_type(from) &&
             (is_add2t(from) || is_sub2t(from) || is_mul2t(from) ||
              is_neg2t(from)) && from->type->get_width() <= type->get_width()) {
    // So, if this is an integer type, performing an integer arith operation,
    // and the type we're casting to isn't _supposed_ to result in a loss of
    // information, push the cast downwards.
    std::list<expr2tc> set2;
    from->foreach_operand([&set2, this] (const expr2tc &e) {
      expr2tc cast = expr2tc(new typecast2t(type, e));
      set2.push_back(cast);
    }
    );

    // Now clone the expression and update its operands.
    expr2tc newobj = expr2tc(from->clone());
    newobj.get()->type = type;

    std::list<expr2tc>::const_iterator it2 = set2.begin();
    newobj.get()->Foreach_operand([this, &it2] (expr2tc &e) {
        e= *it2;
        it2++;
      }
    );

    // Caller won't simplify us further if it's called us with second=true, so
    // give simplification another shot ourselves.
    expr2tc tmp = newobj->simplify();
    if (is_nil_expr(tmp))
      return newobj;
    else
      return tmp;
  } else {
    return expr2tc();
  }

  assert(0 && "Fell through typecast2t::do_simplify");
}

expr2tc
address_of2t::do_simplify(bool second __attribute__((unused))) const
{

  // NB: address of never has its operands simplified below its feet for sanitys
  // sake.
  // Only attempt to simplify indexes. Whatever we're taking the address of,
  // we can't simplify away the symbol.
  if (is_index2t(ptr_obj)) {
    const index2t &idx = to_index2t(ptr_obj);
    const pointer_type2t &ptr_type = to_pointer_type(type);

    // Don't simplify &a[0]
    if (is_constant_int2t(idx.index) &&
        to_constant_int2t(idx.index).constant_value.is_zero())
      return expr2tc();

    expr2tc new_index = idx.index->simplify();
    if (is_nil_expr(new_index))
      new_index = idx.index;

    expr2tc zero = expr2tc(new constant_int2t(index_type2(), BigInt(0)));
    expr2tc new_idx = expr2tc(new index2t(idx.type, idx.source_value, zero));
    expr2tc sub_addr_of = expr2tc(new address_of2t(ptr_type.subtype, new_idx));

    return expr2tc(new add2t(type, sub_addr_of, new_index));
  } else {
    return expr2tc();
  }
}

static expr2tc
do_rel_simplify(const expr2tc &side1, const expr2tc &side2,
                bool (*do_rel)(const fixedbvt &bv1, const fixedbvt &bv2))
{
  fixedbvt bv1, bv2;

  to_fixedbv(side1, bv1);
  to_fixedbv(side2, bv2);

  make_fixedbv_types_match(bv1, bv2);
  bool res = do_rel(bv1, bv2);

  return expr2tc(new constant_bool2t(res));
}

bool
do_fixedbv_eq(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 == bv2;
}

expr2tc
equality2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_eq);
  else
    return expr2tc();
}

bool
do_fixedbv_ineq(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 != bv2;
}

expr2tc
notequal2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_ineq);
  else
    return expr2tc();
}

bool
do_fixedbv_lt(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 < bv2;
}

expr2tc
lessthan2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_lt);
  else
    return expr2tc();
}

bool
do_fixedbv_gt(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 > bv2;
}

expr2tc
greaterthan2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_gt);
  else
    return expr2tc();
}

bool
do_fixedbv_le(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 <= bv2;
}

expr2tc
lessthanequal2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_le);
  else
    return expr2tc();
}

bool
do_fixedbv_ge(const fixedbvt &bv1, const fixedbvt &bv2)
{
  return bv1 >= bv2;
}

expr2tc
greaterthanequal2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_constant_expr(side_1) && is_constant_expr(side_2))
    return do_rel_simplify(side_1, side_2, do_fixedbv_ge);
  else
    return expr2tc();
}

expr2tc
if2t::do_simplify(bool second __attribute__((unused))) const
{
  if (is_constant_expr(cond)) {
    // We can simplify this.
    if (is_constant_bool2t(cond)) {
      if (to_constant_bool2t(cond).constant_value) {
        return true_value;
      } else {
        return false_value;
      }
    } else {
      // Cast towards a bool type.
      expr2tc cast = expr2tc(new typecast2t(type_pool.get_bool(), cond));
      cast = cast->simplify();
      assert(!is_nil_expr(cast) && "We should always be able to cast a "
             "constant value to a constant bool");

      if (to_constant_bool2t(cast).constant_value) {
        return true_value;
      } else {
        return false_value;
      }
    }
  } else {
    return expr2tc();
  }
}

expr2tc
overflow2t::do_simplify(bool second __attribute__((unused))) const
{
  unsigned int num_const = 0;
  bool simplified = false;

  // Non constant expression. We can't just simplify the operand, because it has
  // to remain the operation we expect (i.e., add2t shouldn't distribute itself)
  // so simplify its operands right here.
  if (second)
    return expr2tc();

  expr2tc new_operand = operand->clone();
  new_operand.get()->Foreach_operand([this, &simplified, &num_const] (expr2tc &e) {
      expr2tc tmp = (*e).simplify();
      if (!is_nil_expr(tmp)) {
        e = tmp;
        simplified = true;
      }

      if (is_constant_expr(e))
        num_const++;
    }
  );

  // If we don't have two constant operands, we can't simplify this expression.
  // We also don't want the underlying addition / whatever to become
  // distributed, so if the sub expressions are simplifiable, return a new
  // overflow with simplified subexprs, but no distribution.
  // The 'simplified' test guards against a continuous chain of simplifying the
  // same overflow expression over and over again.
  if (num_const != 2) {
    if (simplified)
      return expr2tc(new overflow2t(new_operand));
    else
      return expr2tc();
  }

  // Can only simplify ints
  if (!is_bv_type(new_operand))
    return expr2tc(new overflow2t(new_operand));

  // We can simplify that expression, so do it. And how do we detect overflows?
  // Perform the operation twice, once with a small type, one with huge, and
  // see if they differ. Max we can do is 64 bits, so if the expression already
  // has that size, give up.
  if (new_operand->type->get_width() == 64)
    return expr2tc();

  expr2tc simpl_op = new_operand->simplify();
  assert(is_constant_expr(simpl_op));
  expr2tc op_with_big_type = new_operand->clone();
  op_with_big_type.get()->type = (is_signedbv_type(new_operand))
                                 ? type_pool.get_int(64)
                                 : type_pool.get_uint(64);
  op_with_big_type = op_with_big_type->simplify();

  // Now ensure they're the same.
  equality2t eq(simpl_op, op_with_big_type);
  expr2tc tmp = eq.simplify();

  // And the inversion of that is the result of this overflow operation (i.e.
  // if not equal, then overflow).
  tmp = expr2tc(new not2t(tmp));
  tmp = tmp->simplify();
  assert(!is_nil_expr(tmp) && is_constant_bool2t(tmp));
  return tmp;
}

// Heavily inspired by cbmc's simplify_exprt::objects_equal_address_of
static expr2tc
obj_equals_addr_of(const expr2tc &a, const expr2tc &b)
{

  if (is_symbol2t(a) && is_symbol2t(b)) {
    if (a == b)
      return true_expr;
  } else if (is_index2t(a) && is_index2t(b)) {
    return obj_equals_addr_of(to_index2t(a).source_value,
                              to_index2t(b).source_value);
  } else if (is_member2t(a) && is_member2t(b)) {
    return obj_equals_addr_of(to_member2t(a).source_value,
                              to_member2t(b).source_value);
  } else if (is_constant_string2t(a) && is_constant_string2t(b)) {
    bool val = (to_constant_string2t(a).value == to_constant_string2t(b).value);
    if (val)
      return true_expr;
    else
      return false_expr;
  }

  return expr2tc();
}

expr2tc
same_object2t::do_simplify(bool second __attribute__((unused))) const
{

  if (is_address_of2t(side_1) && is_address_of2t(side_2))
    return obj_equals_addr_of(to_address_of2t(side_1).ptr_obj,
                              to_address_of2t(side_2).ptr_obj);

  if (is_symbol2t(side_1) && is_symbol2t(side_2) &&
      to_symbol2t(side_1).get_symbol_name() == "NULL" &&
      to_symbol2t(side_1).get_symbol_name() == "NULL")
    return true_expr;

  return expr2tc();
}

expr2tc
concat2t::do_simplify(bool second __attribute__((unused))) const
{

  if (!is_constant_int2t(side_1) || !is_constant_int2t(side_2))
    return expr2tc();

  const mp_integer &value1 = to_constant_int2t(side_1).constant_value;
  const mp_integer &value2 = to_constant_int2t(side_2).constant_value;

  // k; Take the values, and concatenate. Side 1 has higher end bits.
  mp_integer accuml = value1;
  accuml *= (1ULL << side_2->type->get_width());
  accuml += value2;

  return constant_int2tc(type, accuml);
}