I'm trying to use the standard format for non-member function overloading for the ostream operator, but it will not work with a const second argument when I have an internal assignment to a vector iterator. The compiler gives the following error when a const argument is used: error: no match for 'operator=' in j = bus.owAPI::owBus::owCompList.std::vector...
Relevant parts of my Class are as follows:
class owBus{
public:
std::vector<owComponent> owCompList; //unsorted complete list
friend std::ostream&
operator<<(std::ostream& os, const owBus& bus );
};
with the non-member function:
std::ostream& operator<<(std::ostream& os, const owBus& bus ) {
//iterate through component vector
std::vector<owComponent>::iterator j;
for(j=bus.owCompList.begin(); j!=bus.owCompList.end(); j++) {
/*
os << (*j).getComponentID() << ": ";
os << (*j).getComponentType() << std::endl;
*/
}
return os;
}
This works fine if the const is removed from the friend declaration and the second argument in the function description, otherwise it give the error described above. I don't have an assignment operator defined for the class, but it's not clear to me why that should make a difference.
That's because you're trying to use a non-const iterator to iterate through a const object. Change the declaration of j to:
std::vector<owComponent>::const_iterator j;
or just use the C++11 style:
for (auto j : bus.owCompList) {
Related
I wrote a simple program for taking a value through command line into my driver. I used module_param() for this and gave permission argument, i.e third arg of module_param(), as S_IWUSR.
This I guess would allow user to modify the value of that parameter once driver is loaded in the kernel. I tried to modify the value of that parameter by:
echo 1 > /sys/module/ghost/parameters/num
But this shows me Permission denied error every time I try to do this, even when I execute the command with sudo. I also tried changing permission in module_param() to 0770 but still was not able to change the parameter value. Is there a way to change the value of parameter passed while inserting the driver ? Why does the above command shows permission denied, even if I run as sudo ?
After the answer of #Ian Abott I am to change the value of the parameter. Now I tried to define a callback function to notify me any changes in the value of that parameter while my driver is loaded. Here is the code
#include"headers.h"
#include"declarations.h"
static int my_set(const char *val, const struct kernel_param *kp)
{
int n = 0, ret;
ret = kstrtoint(val,10,&n); // Kernel function to convert string to integer
if (ret !=0 || n > 10) {
return -EINVAL;
}
printk(KERN_ALERT "my-set function running\n");
return param_set_int(val,kp);
}
static const struct kernel_param_ops param_ops = {
.set = my_set,
.get = param_get_int,
};
module_param(num,int,0600);
static char *name = "hello";
module_param(name,charp,0770);
static int __init init_func(void)
{
int i;
module_param_cb(callBack, ¶m_ops, &num, 0770);
printk(KERN_INFO "Value of num is %d\n",num);
for( i=0; i<num; i++)
{
printk(KERN_INFO "%s\n", name);
}
return 0;
}
static void __exit exit_func(void)
{
printk(KERN_INFO "Value of num is %d\n",num);
printk(KERN_ALERT "Module removed successfully\n");
}
module_init(init_func);
module_exit(exit_func);
But it doesn't seem to work because my_set function never runs, even if I change the value. My doubt is
1) Is this correct way to implement callback function for the parameter?
2) What is significance of first argument to the function module_param_cb?
I want to wrap the following C++ code into python using pybind
class Galaxy {
public:
double x[3];
double v[3];
};
class GalaxyCatalogue {
public:
long n_tracers;
Galaxy *object;
GalaxyCatalogue(long n_tracers);
~GalaxyCatalogue();
};
GalaxyCatalogue::GalaxyCatalogue(long n_tracers) : n_tracers(n_tracers) {
std::cout << "from galaxies " << n_tracers << std::endl;
object = new Galaxy[n_tracers];
std::cout << "has been allocated " << std::endl;
}
GalaxyCatalogue::~GalaxyCatalogue() {
delete[] object;
}
The first problem I have is that Galaxy doesn't have a constructor, so I'm not sure what to do with that. Even if I declare an empty constructor I don't know how to treat the array in a way that I don't get an error when compiling. This is what I've tried:
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
class Galaxy {
public:
Galaxy();
double x[3];
};
PYBIND11_MODULE(example, m){
py::class_<Galaxy>(m, "Galaxy")
.def(py::init<>())
.def_readwrite("x", &Galaxy::x);
}
This is how I compile it:
c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` gal.cpp -o example`python3-config --extension-suffix`
and this is the error I get:
In file included from gal.cpp:1:
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]’:
gal.cpp:19:33: required from here
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h:1163:65: error: invalid array assignment
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
~~~~~~^~~~~~~
In file included from gal.cpp:1:
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h:64:5: error: ‘pybind11::cpp_function::cpp_function(Func&&, const Extra& ...) [with Func = pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]::<lambda(pybind11::class_<Galaxy>::type&, const double (&)[3])>; Extra = {pybind11::is_method}; <template-parameter-1-3> = void]’, declared using local type ‘pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]::<lambda(pybind11::class_<Galaxy>::type&, const double (&)[3])>’, is used but never defined [-fpermissive]
cpp_function(Func &&f, const Extra&... extra) {
^~~~~~~~~~~~
Thank you in advance.
In C++, you can't assign directly to an array, which is what pybind11 is trying to do inside its wrapping magic. In general, C++ arrays are not great abstractions for numerical arrays. As you've noticed, you can't even say galaxy.x = other_galaxy.x.
Your best bet is to use a higher-level library for matrices and vectors, which will
a) give you a much better experience writing your C++
b) perform better
c) map more cleanly to Python
Eigen is a good choice. pybind11 automatically knows how to map Eigen matrices and vectors to numpy arrays. Your Galaxy would become:
class Galaxy {
public:
Eigen::Vector3d x;
Eigen::Vector3d v;
};
If you absolutely can't do this, you'll have to supply manual getter/setter functions to the property, where you do your own conversion to and from python types:
https://pybind11.readthedocs.io/en/master/classes.html?highlight=def_property#instance-and-static-fields
Is it possible to do implicit/explicit conversion between time_points of two C++11 clocks?
Motivation: chrono::durations provide means of storing time intervals from epoch, conceptually is not equal to a time_point of a custom clock that has an epoch on its own.
Having an implicit conversion between clocks eases up the use Howard Hinnant's date library <date/date.h> which provides means to manipulate and print out time_points of system clocks.
Example:
#include <date/date.h>
using namespace date;
namespace ch = std::chrono;
//
#define EPOCH_OFFSET 100
template<class Duration> using PosixTimePoint =
ch::time_point<ch::system_clock, Duration>;
typedef PosixTimePoint<ch::duration<long,std::micro>> PosixTimePointType;
struct SomeClock{
typedef ch::duration<long,std::micro> duration;
typedef ch::time_point<SomeClock> time_point;
...
static time_point now() noexcept {
using namespace std::chrono;
return time_point (
duration_cast<duration>(
system_clock::now().time_since_epoch()) + date::years(EPOCH_OFFSET) );
}
static PosixTimePoint<duration> to_posix( const time_point& tp ){...}
}
auto tp = SomeClock::now(); //<time_point<SomeClock,ch::duration<long,std::micro>>;
Objective: to convert tp so the std::stream conversions of date.h works and prints out the current time, which in my case is: 2017-12-24 17:02:56.000000
// std::cout << tp; compile error
std::cout << SomeClock::to_posix( tp ); // OK
Explicit cast: this could ease up readability, support conversion feature of the language and facilitate access to date.h routines.
long time_value = static_cast<long>( tp );
auto st = static_cast<PosixTimePointType>( tp );
std::cout << static_cast<PosixTimePointType>( tp );
I recommend mimicking the implementations of either date::utc_clock or date::tai_clock found in tz.h. For example utc_clock implements two functions to convert to and from sys_time:
template<typename Duration>
static
std::chrono::time_point<std::chrono::system_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys(const std::chrono::time_point<utc_clock, Duration>&);
template<typename Duration>
static
std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>&);
So you can think of std::chrono::system_clock as a "hub". Any clock that implements these conversions can convert to any other clock which implements these conversions by bouncing off of system_clock under the covers. And to facilitate that bounce, date::clock_cast is introduced.
Additionally, utc_time can be used as the hub, if that is more efficient for your type. For example tai_clock implements:
template<typename Duration>
static
std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
to_utc(const std::chrono::time_point<tai_clock, Duration>&) NOEXCEPT;
template<typename Duration>
static
std::chrono::time_point<tai_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
from_utc(const std::chrono::time_point<utc_clock, Duration>&) NOEXCEPT;
clock_cast is smart enough to deal with this "dual-hub" system, so one can convert a clock that converts to/from utc_time, to another clock that uses sys_time as its hub.
If you also implement to_stream for your clock, then you can directly use format to format your clock::time_point. And clock_cast is likely to be useful in the implementation of your to_stream function.
Also from_stream can be used to hook your clock::time_point up to date::parse.
Search https://howardhinnant.github.io/date/tz.html for "clock_cast" for example uses of it. For your use case the to_sys/from_sys API appears to be the most useful. Just these two functions will allow you to use clock_cast between your SomeClock and any other clock in tz.h (and any other custom clock that meets these requirements).
Full Demo
#include "date/tz.h"
#include <iostream>
#include <sstream>
struct SomeClock
{
using duration = std::chrono::microseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<SomeClock>;
static constexpr bool is_steady = false;
static time_point now() noexcept
{
return from_sys(date::floor<duration>(std::chrono::system_clock::now()));
}
static constexpr auto offset = date::sys_days{} - date::sys_days{date::year{1870}/1/1};
template<typename Duration>
static
date::sys_time<Duration>
to_sys(const std::chrono::time_point<SomeClock, Duration>& t)
{
return date::sys_time<Duration>{(t - offset).time_since_epoch()};
}
template<typename Duration>
static
std::chrono::time_point<SomeClock, Duration>
from_sys(const date::sys_time<Duration>& t)
{
return std::chrono::time_point<SomeClock, Duration>{(t + offset).time_since_epoch()};
}
};
template <class Duration>
using SomeTime = std::chrono::time_point<SomeClock, Duration>;
constexpr date::days SomeClock::offset;
template <class CharT, class Traits, class Duration>
std::basic_ostream<CharT, Traits>&
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
const SomeTime<Duration>& t)
{
return date::to_stream(os, fmt, date::clock_cast<std::chrono::system_clock>(t));
}
template <class CharT, class Traits, class Duration>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const SomeTime<Duration>& t)
{
const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}};
return to_stream(os, fmt, t);
}
template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
std::basic_istream<CharT, Traits>&
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
SomeTime<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
std::chrono::minutes* offset = nullptr)
{
using namespace date;
sys_time<Duration> st;
date::from_stream(is, fmt, st, abbrev, offset);
if (!is.fail())
tp = clock_cast<SomeClock>(st);
return is;
}
int
main()
{
std::cout << SomeClock::now() << '\n';
std::cout << date::format("%a, %b %d, %Y\n", SomeClock::now());
std::istringstream in{"2017-12-24 19:52:30"};
SomeClock::time_point t;
in >> date::parse("%F %T", t);
std::cout << t << '\n';
}
When trying to expose aligned class like this:
class __declspec(align(16)) foo
{
public:
void foo_method() {}
};
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo>("foo")
.def("foo_method", &foo::foo_method);
}
You end up with error (msvs 2010):
error C2719: 'unnamed-parameter': formal parameter with __declspec(align('16')) won't be aligned,
see reference to class template instantiation 'boost::python::converter::as_to_python_function<T,ToPython>' being compiled
The solution I found so far, is to use smart pointer to store object:
BOOST_PYTHON_MODULE(foo_module)
{
class_<foo, boost::shared_ptr<foo>, boost::noncopyable>("foo")
.def("foo_method", &foo::foo_method);
}
Isn't there a better solution? This is quite annoying, because you should wrap all your functions returning objects by value to return smart pointers instead, and performance also degrades.
I had the same problem and wanted a solution that doesn't involve shared_ptr. It involves specializing some boost::python classes to make sure we get a storage area big enough to be able to align our object within it.
I have written a somewhat long blog post explaining how I arrived at this solution here. Below is the solution I found. I feel it is quite a hack, so maybe it will break other things. But so far it seems to work and I haven't found anything better.
I was trying to expose an Eigen::Quaternionf (which requires 16 bytes alignment) :
bp::class_<Quaternionf>("Quaternion", bp::init<float, float, float, float>())
.def(bp::init<Matrix3f>())
.add_property("w", get_prop_const(&Quaternionf::w))
.add_property("x", get_prop_const(&Quaternionf::x))
.add_property("y", get_prop_const(&Quaternionf::y))
.add_property("z", get_prop_const(&Quaternionf::z))
.def("matrix", &Quaternionf::matrix)
.def("rotvec", &quaternion_to_rotvec);
The solution involves specializing 3 classes :
boost::python::objects::instance to request 16 bytes more than what our type requires to ensure we can align
...
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
...
boost::python::objects::make_instance_impl to correctly set the Py_SIZE of our instance
...
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
...
boost::python::objects::make_instance so that the construct method will align the holder in the storage
...
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage)
QuaternionfHolder(instance, x);
return new_holder;
}
...
The full code is below :
typedef bp::objects::value_holder<Eigen::Quaternionf> QuaternionfHolder;
namespace boost { namespace python { namespace objects {
using namespace Eigen;
//template <class Data = char>
template<>
struct instance<QuaternionfHolder>
{
typedef QuaternionfHolder Data;
PyObject_VAR_HEAD
PyObject* dict;
PyObject* weakrefs;
instance_holder* objects;
typedef typename type_with_alignment<
::boost::alignment_of<Data>::value
>::type align_t;
union
{
align_t align;
char bytes[sizeof(Data) + 16];
} storage;
};
// Adapted from boost/python/object/make_instance.hpp
//template <class T, class Holder, class Derived>
template<class Derived>
struct make_instance_impl<Quaternionf, QuaternionfHolder, Derived>
{
typedef Quaternionf T;
typedef QuaternionfHolder Holder;
typedef objects::instance<Holder> instance_t;
template <class Arg>
static inline PyObject* execute(Arg& x)
{
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >));
PyTypeObject* type = Derived::get_class_object(x);
if (type == 0)
return python::detail::none();
PyObject* raw_result = type->tp_alloc(
type, objects::additional_instance_size<Holder>::value);
if (raw_result != 0)
{
python::detail::decref_guard protect(raw_result);
instance_t* instance = (instance_t*)raw_result;
// construct the new C++ object and install the pointer
// in the Python object.
//Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);
Holder* holder = Derived::construct(
&instance->storage, (PyObject*)instance, x);
holder->install(raw_result);
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast<size_t>(holder)
- reinterpret_cast<size_t>(&instance->storage)
+ offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
// Release ownership of the python object
protect.cancel();
}
return raw_result;
}
};
//template <class T, class Holder>
template<>
struct make_instance<Quaternionf, QuaternionfHolder>
: make_instance_impl<Quaternionf, QuaternionfHolder, make_instance<Quaternionf,QuaternionfHolder> >
{
template <class U>
static inline PyTypeObject* get_class_object(U&)
{
return converter::registered<Quaternionf>::converters.get_class_object();
}
static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper<Quaternionf const> x)
{
LOG(INFO) << "Into make_instance";
LOG(INFO) << "storage : " << storage;
LOG(INFO) << "&x : " << x.get_pointer();
LOG(INFO) << "&x alignment (0 = aligned): " << (reinterpret_cast<size_t>(x.get_pointer()) & 0xf);
// From the specialized make_instance_impl above, we are guaranteed to
// be able to align our storage
void* aligned_storage = reinterpret_cast<void*>(
(reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);
QuaternionfHolder* new_holder = new (aligned_storage) QuaternionfHolder(instance, x);
LOG(INFO) << "&new_holder : " << new_holder;
return new_holder;
//return new (storage) QuaternionfHolder(instance, x);
}
};
}}} // namespace boost::python::objects
I'm sorry if this is vague I'm still pretty new to programming(also new to forums >_>)
Ok, my code is supposed to read in a number from a file, then use that number to read in that amount of words as dictionary words. I then store those words into an array and keep them for later usage. After the dictionary words in the file comes some paragraph, i read that in and set it to c-string array.(iv got that all down so far) But for the last part of the program i need to go back though that paragraph c-string and count how many times each dictionary word appears. I'm currently trying paragraph.find (word[0]) but i get some error that i don't know how to fix.
error: |40|error: request for member 'find' in 'paragraph', which is of non-class type 'char [2000]'|
code:
#include <iostream>
#include <fstream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
ifstream inStream; //declare ifstream
inStream.open("infile2.txt"); //open my file
int number; // number at the begining of the file that lets the program know
inStream >> number; // how many dictionary words are to be expected.
cout << number << " dictionary word(s)" << endl << endl;
char dict[30];
char text[2000];
char paragraph[2000]; // declareing some stuff
int count;
int position;
string word[5];
for (int i=0; i<number; i++) // using c string to set the 'number' amount of words in the dict array
{
inStream.getline(dict,30,'|');
word[i] = dict;
}
for (int i=0; i<number; i++) // cout so i can see its all set up right.
{
cout << "word " << i+1 << " is: " << word[i] << endl;
}
cout << endl;
inStream.get(paragraph,2000,'|'); // setting the rest of the paragrapg of the txt document to a c string
cout << paragraph; // so it can be searched later using the 'dict' words
position = paragraph.find (word[0]); // trying to find the position of the first word stored in 'dict[0]' but i run into an error
return 0;
}
the infile2.txt looks like this:
3steak|eggs|and|
steak and eggs and eggs and steak, eggs and steak, steak and eggs...
delicious.
c-strings are not classes and do not have a find method (or any other methods for that matter) i.e paragraph.find. You could try using a string or if you need to use c-strings a find method that takes two c strings as parameters.
such as This one