I am trying to test the my_vector.cpp program from boost::odeint examples but without any success. I get Segmentation Fault when I run the program.
Compilation: g++ -std=c++14 -o my_vector my_vector.cpp
It runs with std::vector<> instead of my_vector for the state_type. I suspect there is something wrong with is_resizable but I don't know how to fix it.
Here is the code for my_vector.cpp which you can get from github
/*
* Copyright 2011-2012 Mario Mulansky
* Copyright 2012-2013 Karsten Ahnert
*
* 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)
*
* Example for self defined vector type.
*/
#include <vector>
#include <boost/numeric/odeint.hpp>
//[my_vector
template< int MAX_N >
class my_vector
{
typedef std::vector< double > vector;
public:
typedef vector::iterator iterator;
typedef vector::const_iterator const_iterator;
public:
my_vector( const size_t N )
: m_v( N )
{
m_v.reserve( MAX_N );
}
my_vector()
: m_v()
{
m_v.reserve( MAX_N );
}
// ... [ implement container interface ]
//]
const double & operator[]( const size_t n ) const
{ return m_v[n]; }
double & operator[]( const size_t n )
{ return m_v[n]; }
iterator begin()
{ return m_v.begin(); }
const_iterator begin() const
{ return m_v.begin(); }
iterator end()
{ return m_v.end(); }
const_iterator end() const
{ return m_v.end(); }
size_t size() const
{ return m_v.size(); }
void resize( const size_t n )
{ m_v.resize( n ); }
private:
std::vector< double > m_v;
};
//[my_vector_resizeable
// define my_vector as resizeable
namespace boost { namespace numeric { namespace odeint {
template<size_t N>
struct is_resizeable< my_vector<N> >
{
typedef boost::true_type type;
static const bool value = type::value;
};
} } }
//]
typedef my_vector<3> state_type;
void lorenz( const state_type &x , state_type &dxdt , const double t )
{
const double sigma( 10.0 );
const double R( 28.0 );
const double b( 8.0 / 3.0 );
dxdt[0] = sigma * ( x[1] - x[0] );
dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
dxdt[2] = -b * x[2] + x[0] * x[1];
}
using namespace boost::numeric::odeint;
int main()
{
state_type x(3);
x[0] = 5.0 ; x[1] = 10.0 ; x[2] = 10.0;
// my_vector works with range_algebra as it implements
// the required parts of a container interface
// no further work is required
integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , 0.1 );
}
I can reproduce this with g++-4.8.
I've opened an issue on this at the odeint github repository:
https://github.com/headmyshoulder/odeint-v2/issues/180
edit:
I've found the problem and solved it: https://github.com/headmyshoulder/odeint-v2/commit/965a8e456d5e9dff47f0121a4d12aac8c845ea5e
The problem was an inconsistent template parameter type that prevented the is_resizeable definition to work properly, as expected by the op already.
changing the my_ vector template parameter type to size_t fixes this:
template<size_t N>
class my_vector
Related
Im tring to assign a float number with an expression when declare it.
But I got but I get wrong result and msvc2019 warns me about use of uninitialized variable.
template <int N, typename Viewer, typename Point = std::array<float, N>>
struct PixelToCoordinateWrapper;
template <typename Viewer, typename Point>
struct PixelToCoordinateWrapper<2, Viewer, Point> {
static constexpr auto Impl = [](float px, float py,
const Viewer &viewer) -> Point {
float ratio_x;
ratio_x = px / viewer.ViewPortWidth();
// This is OK
float ratio_y = py / viewer.ViewPortHeight();
std::cout << ratio_y; // wrong value.
// warning C4700: uninitialized local variable 'ratio_y' used
float r_wh = viewer.ViewPortScaleX() / viewer.ViewPortScaleY();
std::cout << r_wh; // wrong value
// warning C4700: uninitialized local variable 'r_wh' used
float offset_x, offset_y;
if (viewer.LengthX() / viewer.LengthY() > r_wh) {
offset_x = viewer.LengthX() * ratio_x;
offset_y = viewer.LengthX() * ratio_y;
offset_y = offset_y / r_wh;
} else {
offset_x = viewer.LengthY() * ratio_x;
offset_y = viewer.LengthY() * ratio_y;
offset_x = offset_x * r_wh;
}
return {viewer.CenterX() - viewer.LengthX() / 2 + offset_x,
viewer.CenterY() - viewer.LengthY() / 2 + offset_y};
};
};
And some relevant codes:
template <typename Viewer, typename ObjectContainer, typename Point>
struct SelectPolygonWrapper<2, Viewer, ObjectContainer, Point> {
static constexpr auto Impl = [](ObjectContainer *gl_object_container,
const Viewer &viewer, const float px,
const float py) -> int {
using RawViewerType = std::remove_cv_t<std::remove_reference_t<Viewer>>;
Point p = PixelToCoordinateWrapper<2, RawViewerType, Point>::Impl(px, py,
viewer);
return PointInPolygonWrapper<2, Point, ObjectContainer>::Impl(
gl_object_container, p);
};
template <int N, typename Point, typename ObjectContainer>
struct PointInPolygonWrapper;
template <typename Point, typename ObjectContainer>
struct PointInPolygonWrapper<2, Point, ObjectContainer> {
/// Return the index of the gl_object in container.
/// If no gl_object is selected, return -1.
static constexpr auto Impl = [](ObjectContainer *gl_object_container,
const Point &point) -> int { return -1; };
};
The following is the main program code where the error occurs:
int count = SelectPolygonWrapper<
2, Viewer, ObjectContainer>::Impl(draw_object_, viewer_,
event->position().x(),
event->position().y());
/// Wrong
However, when I call PixelToCoordinateWrapper::Impl directly, the result is correct, and the compiler gives me no warning.
auto p = PixelToCoordinateWrapper<2, ViewerInfo>::Impl(
event->position().x(), event->position().y(), viewer_);
} /// Right
I don't understand what's going on here, is there something wrong with the instantiation of the class template? Or is it an implementation issue with the MSVC compiler?
I have an application with several boost::variants which share many of the fields. I would like to be able to compose these visitors into visitors for "larger" variants without copying and pasting a bunch of code. It seems straightforward to do this for non-recursive variants, but once you have a recursive one, the self-references within the visitor (of course) point to the wrong class. To make this concrete (and cribbing from the boost::variant docs):
#include "boost/variant.hpp"
#include <iostream>
struct add;
struct sub;
template <typename OpTag> struct binop;
typedef boost::variant<
int
, boost::recursive_wrapper< binop<add> >
, boost::recursive_wrapper< binop<sub> >
> expression;
template <typename OpTag>
struct binop
{
expression left;
expression right;
binop( const expression & lhs, const expression & rhs )
: left(lhs), right(rhs)
{
}
};
// Add multiplication
struct mult;
typedef boost::variant<
int
, boost::recursive_wrapper< binop<add> >
, boost::recursive_wrapper< binop<sub> >
, boost::recursive_wrapper< binop<mult> >
> mult_expression;
class calculator : public boost::static_visitor<int>
{
public:
int operator()(int value) const
{
return value;
}
int operator()(const binop<add> & binary) const
{
return boost::apply_visitor( *this, binary.left )
+ boost::apply_visitor( *this, binary.right );
}
int operator()(const binop<sub> & binary) const
{
return boost::apply_visitor( *this, binary.left )
- boost::apply_visitor( *this, binary.right );
}
};
class mult_calculator : public boost::static_visitor<int>
{
public:
int operator()(int value) const
{
return value;
}
int operator()(const binop<add> & binary) const
{
return boost::apply_visitor( *this, binary.left )
+ boost::apply_visitor( *this, binary.right );
}
int operator()(const binop<sub> & binary) const
{
return boost::apply_visitor( *this, binary.left )
- boost::apply_visitor( *this, binary.right );
}
int operator()(const binop<mult> & binary) const
{
return boost::apply_visitor( *this, binary.left )
* boost::apply_visitor( *this, binary.right );
}
};
// I'd like something like this to compile
// class better_mult_calculator : public calculator
// {
// public:
// int operator()(const binop<mult> & binary) const
// {
// return boost::apply_visitor( *this, binary.left )
// * boost::apply_visitor( *this, binary.right );
// }
// };
int main(int argc, char **argv)
{
// result = ((7-3)+8) = 12
expression result(binop<add>(binop<sub>(7,3), 8));
assert( boost::apply_visitor(calculator(),result) == 12 );
std::cout << "Success add" << std::endl;
// result2 = ((7-3)+8)*2 = 12
mult_expression result2(binop<mult>(binop<add>(binop<sub>(7,3), 8),2));
assert( boost::apply_visitor(mult_calculator(),result2) == 24 );
std::cout << "Success mult" << std::endl;
}
I would really like something like that commented out better_mult_expression to compile (and work) but it doesn't -- because the this pointers within the base calculator visitor don't reference mult_expression, but expression.
Does anyone have suggestions for overcoming this or am I just barking down the wrong tree?
Firstly, I'd suggest the variant to include all possible node types, not distinguishing between mult and expression. This distinction makes no sense at the AST level, only at a parser stage (if you implement operator precedence in recursive/PEG fashion).
Other than that, here's a few observations:
if you encapsulate the apply_visitor dispatch into your evaluation functor you can reduce the code duplication by a big factor
your real question seems not to be about composing variants, but composing visitors, more specifically, by inheritance.
You can use using to pull inherited overloads into scope for overload resolution, so this might be the most direct answer:
Live On Coliru
struct better_mult_calculator : calculator {
using calculator::operator();
auto operator()(const binop<mult>& binary) const
{
return boost::apply_visitor(*this, binary.left) *
boost::apply_visitor(*this, binary.right);
}
};
IMPROVING!
Starting from that listing let's shave off some noise!
remove unncessary AST distinction (-40 lines, down to 55 lines of code)
generalize the operations; the <functional> header comes standard with these:
namespace AST {
template <typename> struct binop;
using add = binop<std::plus<>>;
using sub = binop<std::minus<>>;
using mult = binop<std::multiplies<>>;
using expr = boost::variant<int,
recursive_wrapper<add>,
recursive_wrapper<sub>,
recursive_wrapper<mult>>;
template <typename> struct binop { expr left, right; };
} // namespace AST
Now the entire calculator can be:
struct calculator : boost::static_visitor<int> {
int operator()(int value) const { return value; }
template <typename Op>
int operator()(AST::binop<Op> const& binary) const {
return Op{}(boost::apply_visitor(*this, binary.left),
boost::apply_visitor(*this, binary.right));
}
};
Here your variant can add arbitrary operations without even needing to touch the calculator.
Live Demo, 43 Lines Of Code
Like I mentioned starting off, encapsulate visitation!
struct Calculator {
template <typename... T> int operator()(boost::variant<T...> const& v) const {
return boost::apply_visitor(*this, v);
}
template <typename T>
int operator()(T const& lit) const { return lit; }
template <typename Op>
int operator()(AST::binop<Op> const& bin) const {
return Op{}(operator()(bin.left), operator()(bin.right));
}
};
Now you can just call your calculator, like intended:
Calculator calc;
auto result1 = calc(e1);
It will work when you extend the variant with operatios or even other literal types (like e.g. double). It will even work, regardless of whether you pass it an incompatible variant type that holds a subset of the node types.
To finish that off for maintainability/readability, I'd suggest making operator() only a dispatch function:
Full Demo
Live On Coliru
#include <boost/variant.hpp>
#include <iostream>
namespace AST {
using boost::recursive_wrapper;
template <typename> struct binop;
using add = binop<std::plus<>>;
using sub = binop<std::minus<>>;
using mult = binop<std::multiplies<>>;
using expr = boost::variant<int,
recursive_wrapper<add>,
recursive_wrapper<sub>,
recursive_wrapper<mult>>;
template <typename> struct binop { expr left, right; };
} // namespace AST
struct Calculator {
auto operator()(auto const& v) const { return call(v); }
private:
template <typename... T> int call(boost::variant<T...> const& v) const {
return boost::apply_visitor(*this, v);
}
template <typename T>
int call(T const& lit) const { return lit; }
template <typename Op>
int call(AST::binop<Op> const& bin) const {
return Op{}(call(bin.left), call(bin.right));
}
};
int main()
{
using namespace AST;
std::cout << std::boolalpha;
auto sub_expr = add{sub{7, 3}, 8};
expr e1 = sub_expr;
expr e2 = mult{sub_expr, 2};
Calculator calc;
auto result1 = calc(e1);
std::cout << "result1: " << result1 << " Success? " << (12 == result1) << "\n";
// result2 = ((7-3)+8)*2 = 12
auto result2 = calc(e2);
std::cout << "result2: " << result2 << " Success? " << (24 == result2) << "\n";
}
Still prints
result1: 12 Success? true
result2: 24 Success? true
The following program which is supposed to emulate std::vector. I am using Eclipse IDE for C/C++ Developers
Version: Neon.3 Release (4.6.3)
Build id: 20170314-1500
and my c++ version is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
is flagging error that "function std::move could not be resolved".
What is the possible reason for this error ?
//============================================================================
// Name : data_structure_1.cpp
// Author : Manish Sharma
// Description : Programme to implement a simple vector class named "Vector".
// Reference : Data Structures and Algo. analysis in c++, Mark Allen Weiss
//============================================================================
#include <iostream>
#include <algorithm>
using namespace std;
template<class Object>
class Vector{
public:
// constructor
explicit Vector(int initSize = 0):
theSize{initSize},
theCapacity{initSize + SPARE_CAPACITY},
objects{new Object[theCapacity]}{
}
// copy constructor
Vector(const Vector& rhs):
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{new Object[theCapacity]}{
for(int k = 0;k<theSize; ++k){
objects[k] = rhs.objects[k];
}
}
// copy assignment operaor
Vector & operator= (const Vector & rhs){
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
//class destructor
~Vector(){
delete[] objects;
}
//c++ 11 additions, reference to rvalues
Vector(Vector&& rhs) :
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{rhs.objects}{
cout<<endl<<"Inside lvalue reference constructor";
//if you forget to include this then when rhs will you destroyed
//you will be left with a dangling pointer
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
// copy assignment operaor
Vector & operator= (Vector && rhs){
cout<<endl<<"Inside lvalue reference copy";
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
void resize(int newSize){
if(newSize > theCapacity)
reserve(newSize*2);
theSize = newSize;
}
void reserve(int newCapacity){
if(newCapacity<theSize)
return;
Object *newArray = new Object[newCapacity];
cout<<endl<<"moving inside reserve";
for(int k=0;k<theSize;++k){
newArray[k] = std::move(objects[k]);
}
theCapacity = newCapacity;
std::swap(objects,newArray);
delete[] newArray;
}
//Some extra useful functions
int size() const{
return theSize;
}
bool empty() const{
return size()==0;
}
int capacity() const{
return theCapacity;
}
void increaseCapacity(){
reserve(2*theCapacity+1);
}
//insertion and deletion functions
void push_back(const Object & x){
if(theSize == theCapacity){
increaseCapacity();
}
cout<<endl<<"Moving inside push_back";
objects[theSize++] = std::move(x);
}
void pop_back(){
--theSize;
}
using iterator = Object*;
using const_iterator = const Object*;
iterator begin(){
return &objects[0];
}
const_iterator begin() const{
return &objects[0];
}
iterator end(){
return &objects[size()];
}
const_iterator end() const{
return &objects[size()];
}
//class specific constants
static const int SPARE_CAPACITY = 16;
private:
int theSize;
int theCapacity;
Object * objects;
};
int main() {
Vector<int> my_vector;
my_vector.push_back(10);
int j{24};
my_vector.push_back(j);
for(int i = 0;i<20;i++){
my_vector.push_back(i*10);
}
cout<<"\nSize = "<<my_vector.size()<<endl;
my_vector.capacity();
for(auto it = my_vector.begin();it!=my_vector.end();++it){
cout<<*it<<", ";
}
return 0;
}
In my app I would like to pass in a parameter pack over a legacy function signature, and change the values. Here is code that illustrates my question with my attempts as comments:
#include <tuple>
#include <cassert>
void LegacySignature( void* param );
template< typename... ArgsT >
// using ???; // attempt: can 'template alias' or 'using declaration' make the pack's type visible so I can use it inside the LegacyFunction?
void MyFunc( ArgsT&... args )
{
auto userArgsTuple = std::forward_as_tuple< ArgsT&... >( args... );
LegacySignature( &userArgsTuple );
}
void LegacySignature( void* param )
{
// auto userArgsTuple = reinterpret_cast<???>( param ); // attempt: how can I get the parameter pack's type declared so I can use it here?
// do something with the params like change num to 44 and tf to true;
//userArgsTuple->num = 44; // desired functionality
//userArgsTuple->tf = true; // desired functionality
}
int main()
{
int num { 33 };
bool tf { false };
MyFunc( num, tf );
assert( num == 44 && tf == true );
return 0;
}
Is there a way to make the parameter pack a declarable lvalue?
I'm assuming what you want is a function pointer to your legacy signature.
Here is a C++11 approach.
template<class Sig, class F>
struct magic_callback_t;
template<class R, class...Args, class F>
struct magic_callback_t<R(Args...), F> {
F f;
void* pvoid() const { return this; }
using result_sig = R(*)(void*, Args...);
result_sig pfunc() const {
return [](void* pvoid, Args...args)->R{
auto* self = static_cast<magic_callback_t*>(pvoid);
return (self->f)(std::forward<Args>(args)...);
};
}
};
template<class Sig, class F>
magic_callback_t<Sig, F> magic_callback( F&& f ) {
return {std::forward<F>(f)};
}
Now we just do this:
auto callback = magic_callback( [&](){
// use whatever as if we where in the enclosing scope
});
void(*)(void*) legacy_ptr = callback.pfunc();
legacy_ptr( callback.pvoid() );
will call the lambda you passed to magic_callback.
If you want to store stuff as a tuple, you can. Just capture the tuple in the lambda, then use std::get to access it in the body of the lambda. Use mutable if you want it to be mutable.
The code below fixes the sample code so that it answers the question as to how to pass a parameter pack over a legacy function signature using forward_as_tuple.
#include <tuple>
#include <cassert>
#include <memory>
#include <functional>
#define ARGSET int, bool
void LegacySignature( long* param ); // ie, LPARAM
template< typename... ArgsT >
struct MyParams
{
MyParams( ArgsT... args ) : rvalRefs { std::forward_as_tuple( args... ) } {} // The resulting forward_as_tuple tuple has rvalue reference data members
std::tuple< ArgsT... > rvalRefs;
};
void LegacySignature( long* legSigParam )
{
auto userArgsTuple( reinterpret_cast< MyParams< ARGSET >* >( legSigParam ) );
// do something with the params like change num to 44 and tf to true;
std::get< 0 >( userArgsTuple->rvalRefs ) = 44; // index types can probably be worked out using enums
std::get< 1 >( userArgsTuple->rvalRefs ) = true;
}
int main()
{
int num { 33 };
bool tf { false };
MyParams< ARGSET > myParams( num, tf );
std::unique_ptr< MyParams< ARGSET > > legSigParamPtr = std::make_unique< MyParams< ARGSET > >( myParams );
LegacySignature( ( long* )legSigParamPtr.get() );
assert( std::get< 0 >( legSigParamPtr->rvalRefs ) == 44 && std::get< 1 >( legSigParamPtr->rvalRefs ) == true );
return 0;
}
I'm writing a generic short vector class with a union to do type punning so I can swizzle the components. For example, if I declare Vector3 v3. I can access v3.yz as a Vector2. The following code works fine wit GCC 4.8 with -std=c++11 (or c++1y) and whatever version of Clang comes with Xcode 7.1.
However, it does not compile on Visual Studio 2015 with Update 1, using either the msvc or the Clang 3.7 toolkits:
#include <cstdint>
#include <cstdio>
template< int d, typename T, typename Derived >
class VectorBase
{
public:
VectorBase()
{
for( int i = 0; i < d; ++i )
{
( *this )[ i ] = T( 0 );
}
}
const T& operator [] ( int i ) const
{
return static_cast< const Derived* >( this )->elements[ i ];
}
T& operator [] ( int i )
{
return static_cast< Derived* >( this )->elements[ i ];
}
};
template< typename T >
class Vector2 : public VectorBase< 2, T, Vector2< T > >
{
public:
typedef VectorBase< 2, T, Vector2 > Base;
using Base::Base;
union
{
struct
{
T x;
T y;
};
T elements[ 2 ];
};
};
template< typename T >
class Vector3 : public VectorBase< 3, T, Vector3< T > >
{
public:
typedef VectorBase< 3, T, Vector3 > Base;
using Base::Base;
union
{
struct
{
T x;
T y;
T z;
};
struct
{
Vector2< T > xy;
};
struct
{
float __padding0;
Vector2< T > yz;
};
T elements[ 3 ];
};
};
int main( int argc, char* argv[] )
{
Vector2< float > v2;
Vector3< float > v3;
printf( "v2 has size %zu, .x = %f, .y = %f\n", sizeof( v2 ), v2.x, v2.y );
printf( "v3 has size %zu, .x = %f, .y = %f, .z = %f\n", sizeof( v3 ), v3.x, v3.y, v3.z );
}
VS 2015 complains with the error message:
1> main.cpp
1>main.cpp(79,22): error : call to implicitly-deleted default constructor of 'Vector3<float>'
1> Vector3< float > v3;
1> ^
1> main.cpp(63,9) : note: default constructor of 'Vector3<float>' is implicitly deleted because variant field '' has a non-trivial default constructor
1> struct
1> ^
1> 1 error generated.
It makes sense that the compiler thinks the default constructor is nontrivial and implicitly deletes it. What doesn't make sense is why inheriting the constructor with the using declaration fail, and the difference between compilers.
I can make it work by explicitly adding a Vector3 constructor that explicitly calls the VectorBase constructor in the initialization list, but that somewhat defeats the purpose of using the CRTP.