how to declare and then initialize a parquet arrow::Rand omAccessFile in C++ - c++

I am trying to readapt this piece of code of the parquet C++ documentation to open a parquet file with a FileReader to get the minimum value of a column.
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::shared_ptr<arrow::io::RandomAccessFile> input;
ARROW_ASSIGN_OR_RAISE(input, arrow::io::ReadableFile::Open(path_to_file));
// Open Parquet file reader
std::unique_ptr<parquet::arrow::FileReader> arrow_reader;
ARROW_RETURN_NOT_OK(parquet::arrow::OpenFile(input, pool, &arrow_reader));
// Read entire file as a single Arrow table
std::shared_ptr<arrow::Table> table;
ARROW_RETURN_NOT_OK(arrow_reader->ReadTable(&table));
However, the macro ARROW_ASSIGN_OR_RAISE_ERROR is causing the error:
error: cannot convert 'const arrow::Status' to 'int' in return
27 | ARROW_ASSIGN_OR_RAISE(input, arrow::io::ReadableFile::Open(parquet_path.c_str()));
| ^
| |
| const arrow::Status
The macro documentation says:
Execute an expression that returns a Result, extracting its value into the variable defined by lhs (or returning a Status on error).
So I tried to do the passages explicitly separating the initialisation from the declaration, something like:
std::shared_ptr<arrow::io::RandomAccessFile> input(nullptr);
input = std::make_shared<arrow::io::RandomAccessFile>(arrow::io::ReadableFile::Open(parquet_path.c_str()));
but I am getting the error
error: invalid new-expression of abstract class type 'arrow::io::RandomAccessFile'
146 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
How can I initialize the shared pointer of arrow::io::RandomAccessFile after the declaration?

You don't need std::make_shared, arrow::io::ReadableFile::Open() returns a shared pointer.
std::shared_ptr<arrow::io::RandomAccessFile> input =
arrow::io::ReadableFile::Open(parquet_path.c_str()).ValueOrDie();

Related

how to initialize a pointer to a function inside a class that is used as value in a map?

I am writing a program whose behaviour is to be controlled by user-defined settings, provided through a plain ASCII configuration file including keywords and values.
Since not all keywords may be provided by the user, there are also "built-in" settings.
The configuration values provided for different keywords will affect variables (all part of settings class) that will, in turn, determine the program's behaviour.
To translate the configuration values to these variables, I want to use parsing functions - one per configuration keyword.
To achieve this, I use a map, with a configuration keyword as a key, and a param_struct object as a value.
param_struct contains the default value for the configuration keyword, the value read from configuration file (which may be empty), and a pointer to a parsing function.
As a first step, I am trying to initialize the default values, but I keep getting compilation errors. Is there anything am I doing fundamentally wrong here?
settings.cpp: In member function 'std::map<std::__cxx11::basic_string<char>, param_struct> settings::create_builtin_config()':
settings.cpp:84:96: error: no matching function for call to 'param_struct::param_struct(const char [6], const char [1], <unresolved overloaded function type>)'
84 | map<string, param_struct> builtin_config = {{"MY_CONFIG_KEYWORD", param_struct("XYZZY","", update_log)}}; //
| ^
settings.cpp:84:98: error: could not convert '{{"MY_CONFIG_KEYWORD", <expression error>}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, param_struct>'
84 | map<string, param_struct> builtin_config = {{"MY_CONFIG_KEYWORD", param_struct("XYZZY","", update_log)}}; //
| ^
| |
| <brace-enclosed initializer list>
// settings.h file
typedef void (*param_setter) (string, string);
class param_struct {
string default_value; // built-in default configuration value
string loaded_value; // configuration value loaded from the
param_setter parsing_function;
// param_setter parsing_function; // pointer to the respective parsing/initialization function
public:
friend class settings;
param_struct();
param_struct(string, string, param_setter);
~param_struct();
};
class settings {
map<string,param_struct> config_params; // keywords and the respective values + parsing/initialization functions
/* lots of other declarations skipped */
map <string, param_struct> create_builtin_config();
public:
void update_log(string builtin_param, string user_param); // dummy function that does nothing, except writing a log entry. used to test config parameter parsing
friend class param_struct;
}
//settings.cpp file:
settings::settings() {
config_params = create_builtin_config();
}
map<string, param_struct> settings::create_builtin_config() {
map<string, param_struct> builtin_config = {{"MY_CONFIG_KEYWORD", param_struct("XYZZY","", update_log)}}; //
return builtin_config;
}
param_struct::param_struct(string defaultval, string loaded, param_setter parser_fn) {
default_value = defaultval;
loaded_value = loaded;
parsing_function = parser_fn;
}
update_log is a member function.
Your param_setter type is a free function.
They don't match.
A member function has an implicit first argument -- a pointer to the class -- and isn't compatibile with free function pointers.
The easy solution is to store a std::function<void(string,string)>, then pass in [this](string s1, string s2){ update_log(s1, s2); }. This also makes explicit that you are passing in a pointer to the object here; as you are storing it, you'll want to delete your move/copy construct/assignment operators, or you'll get very surprising results.
Another option is to make update_log a static member function, which is compatible with a free function of the same signature. You lose access to the state of your class object, however.

Create a pointer to a MFnMesh

I am trying to create function that receive a MFnMesh pointer and do things on it.
The problem is that I cannot convert my MFnMesh to a pointer, I think the problem is not only on this class but on MFnBaseClass because I get this error.
/usr/autodesk/maya2015-x64/include/maya/MFnBase.h:168:14: error: ‘MFnMesh* MFnMesh::operator&() const’ is private
MFnClass * operator& () const
^
/usr/autodesk/maya2015-x64/include/maya/MFnDagNode.h:237:2: note: in expansion of macro ‘declareMinimalMFn’
declareMinimalMFn( MFnClass ); \
^
/usr/autodesk/maya2015-x64/include/maya/MFnMesh.h:243:2: note: in expansion of macro ‘declareDagMFn’
declareDagMFn(MFnMesh, MFnDagNode);
^
/home/k.masson/Documents/maya/km_extendedColorSet/src/km_particlesToColorSet.cpp:159:9: error: within this context
test(&meshFn);
^
Here is the function test which is in somefile.h and included in the file which call the function.
void test(MFnMesh * meshFn){
MStatus status = MS::kSuccess;
MString csName("YOLOSWAQDAZD");
status = meshFn->createColorSetDataMesh(csName);
MCheckStatus(status,"Error creating new color set");
}
And here is what I do before calling the test function.
// Get the out mesh data
MDataHandle outMeshHandle = data.outputValue(aOutGeometry, &status);
MCheckStatus(status,"ERROR getting aOutGeometry");
// Copy the in mesh to the output
outMeshHandle.copy(inMeshData);
// Create a function set for the out mesh
MFnMesh meshFn(outMeshHandle.asMesh());
test(&meshFn);
I didn't found any way to convert my MFnMesh to a pointer so I tried to directly call it as an object and not a pointer like this.
test(meshFn);
void test(MFnMesh meshFn){
MStatus status = MS::kSuccess;
MString csName("YOLOSWAQDAZD");
status = meshFn.createColorSetDataMesh(csName);
MCheckStatus(status,"Error creating new color set");
}
And I get this :
/usr/autodesk/maya2015-x64/include/maya/MFnMesh.h:243:16: error: ‘MFnMesh::MFnMesh(const MFnMesh&)’ is private
declareDagMFn(MFnMesh, MFnDagNode);
^
/usr/autodesk/maya2015-x64/include/maya/MFnBase.h:166:9: note: in definition of macro ‘declareMinimalMFn’
MFnClass( const MFnClass &rhs ); \
^
/usr/autodesk/maya2015-x64/include/maya/MFnMesh.h:243:2: note: in expansion of macro ‘declareDagMFn’
declareDagMFn(MFnMesh, MFnDagNode);
^
/home/k.masson/Documents/maya/km_extendedColorSet/src/km_particlesToColorSet.cpp:159:14: error: within this context
test(meshFn);
^
In file included from /home/k.masson/Documents/maya/km_extendedColorSet/src/km_particlesToColorSet.cpp:29:0:
/home/k.masson/Documents/maya/km_extendedColorSet/src/kmColorSetTool.h:29:6: error: initializing argument 1 of ‘void test(MFnMesh)’
void test(MFnMesh meshFn){
So do you know if there is anyway to create a function that acts on a MFnBase class in a fashion way, or even a class with a MFnBase attribute ? I don't know we can't do this kind of process which is really current..
I am new to c++ so it may be possible that I did a dumb mistake.
The MFnBaseClass does not allow to use the conversion to a pointer, instead, use a reference which works almost the same. See References vs. Pointers for more information.
The correct signature for my function is
void test(MFnMesh& meshFn)
And the way to use it is
test(meshFn);
And to use the reference in the function, just use it as a regular object
void test(MFnMesh& meshFn){
MStatus status = MS::kSuccess;
MString csName("YOLOSWAQDAZD");
status = meshFn.createColorSetDataMesh(csName);
MCheckStatus(status,"Error creating new color set");
}

Compilation results in an error when trying to compile code containing binary ifstream

I am running into a problem with the accessing a binary file via the input file stream class (ifstream).
My approach starts with the following calling function:
void ReadFile(vector<string>& argv, ostream& oss){
string FileName = argv.at(2) + "INPUT" ;
ifstream BinFile ;
OpenBinaryFile(FileName, BinFile) ;
return ;
}
The called function looks like this:
void OpenBinaryFile(string& FileName, ifstream& BinFile){
using namespace std ;
BinFile(FileName.c_str(),ifstream::binary | ifstream::in) ;
}
When I try to compile this simple scheme using gcc version 4.9.2 I get the following error:
error: no match for call to ‘(std::ifstream {aka std::basic_ifstream<char>}) (const char*, std::_Ios_Openmode)’
BinFile(FileName.c_str(),ifstream::binary | ifstream::in) ;
^
I've tried to get the caret ("^") placed exactly where the compiler did.
What's going on here? I am baffled.
Thanks!
There are two ways of opening a stream.
During construction, in a declaration:
std::ifstream BinFile(filename, std::ifstream::binary | std::ifstream::in);
After construction, using the std::ifstream::open function:
std::ifstream BinFile;
BinFile.open(filename, std::ifstream::binary | std::ifstream::in);
In your question you are attempting to mix the two. This results in an attempt to call the non-existent "function call operator" operator() on the object BinFile.
As written, you were calling a constructor with the object that had already been constructed on the stack of the calling routine. See the constructor documented at http://www.cplusplus.com/reference/fstream/ifstream/ifstream/

Redirecting stdout to LCD: pointer of member class

FILE *LCD_stdout = new FILE();
int (*ptr)(char, FILE *) = ROBOT::__LCD_putchar;
fdev_setup_stream(LCD_stdout, ptr, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
gives me error:
In member function 'SUBSYS_OPENSTAT ROBOT::LCD_open()':
LCD.cpp:108: error: argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)'
I've looked at a number of solutions through Stack Overflow and whatnot. .* doesn't resolve it, tried assigning a pointer of a pointer, and I feel I'm likely not going to be resolve it without resolving misconceptions.
The compiler error tells you exactly what's wrong:
argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)
...because pointers to member functions aren't compatible with pointers to non-member functions, for a couple of reasons.
One option is to create a separate free function but this depends on where the ROBOT object resides. For example if you have a global ROBOT object you could do the following
ROBOT globalRobot;
int callback(char c, FILE* f)
{
return globalRobot.__LCD_putchar(c, f);
}
FILE *LCD_stdout = new FILE();
fdev_setup_stream(LCD_stdout, callback, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
If there is only going to be one robot object and it is a member variable of another class change globalRobot to be a pointer and set it after the ROBOT object has been created (ROBOT's constructor maybe)
This is untested as I don't know the innards of ROBOT but everything looks ok.

Enumeration type as return value in soapcpp2

I'm creating a web service using gSoap, in the header file I have few method definitions that their return type is enum value.
When I'm executing the soapcpp2.exe tool and passing with the header file I'm getting this error:
sample.h(20): syntax error
sample.h(21): Syntax error: input before ; skipped
In addition, if I have more than one method with the enum as the return value I'm getting this warning:
**WARNING**: Duplicate declaration of 'sample_status_____' (already declared at li
ne 31), changing conflicting identifier name to new name sample_status______'. Note: this problem may be caused by importing invalid XML schemas (detected at line 38 in sample.h)
My header file looks such like:
// enum definition
enum status {ok, error};
// method definition
status ns_calc(int a, int b);
Is it a limitation with soapcpp.exe?
The header file you are writting has to follow some gSoap conventions. Therefore the output of the function has to be the last argument. From the documentation:
By convention, all parameters are input parameters except the last. The last parameter is always the output parameter. A struct or class is used to wrap multiple output parameters, see also Section 7.1.9. This last parameter must be a pointer or reference. By contrast, the input parameters support pass by value or by pointer, but not pass by C++ reference.
The relevant part in the header file would look like:
enum ns__status { ok, error };
int ns__calc(xsd__int a, xsd__int b, enum ns__status& out);
Note that this example explicitly uses XML-Schema (xsd__) types, this practice is advised to improve interoperability. The relevant part in the cpp file would look like:
int ns__calc(struct soap* soap, xsd__int a, xsd__int b, enum ns__status& out)
{
// do something with 'a' and 'b' and set 'out'
out = ...
return SOAP_OK;
}