Inline cast of char types - casting

Does abap have any method to perform an inline cast for char types (or any similar types of different length)? Perhaps there is something similar to value operator( for structures) that can be used for fields.
Concrete example (name is of type tdobname, which is char 70 and ebeln is char 10) that leads to a dump due to type mismatch:
call function 'READ_TEXT'
exporting
id = lv_textid
language = sy-langu
name = ls_ekko-ebeln
object = 'EKKO'
tables
lines = lt_textlines
For now I added an line of conversion to a variable of destination type (which works), but I am hoping to skip that step.
data: lv_name type tdobname.
lv_name = ls_ekko-ebeln.
call function 'READ_TEXT'
exporting
...
name = lv_name
...

Use CONV operator for that:
DATA(lv_name) = CONV tdobname( ls_ekko-ebeln ).

Related

Is there a non-hacky way in libfmt to construct names for named arguments at runtime?

I am using libfmt to build a code generator that generates a sort of adapter layer around an existing library. So I have a dataset of parameter descriptions that include format strings describing the conversion from the data type in the outer layer to the data type in the inner layer. In the most simple case, this might look like
"{type_out} {var_out} = {var_in};\n"
in a more complex case, the conversion might depend on another parameter:
"int {var_out} = function_call({var_in}, {dependent_param__var_out});\n"
The name dependent_param (and as such any name that refers to one of its attributes, such as dependent_param__var_out) is not known to the code generator at compile time; it's constructed at runtime from the parameter dataset.
This means that I need to build a fmt::dynamic_format_arg_store some of whose named arguments are constructed at runtime. In essence, what I would like is along the lines of
#include <fmt/args.h>
#include <fmt/format.h>
#include <string>
fmt::dynamic_format_arg_store<fmt::format_context>
construct_arg_store(std::string const &paramname) {
fmt::dynamic_format_arg_store<fmt::format_context> fmt_args;
// so far, so good.
fmt_args.push_back(fmt::arg("var_in", paramname));
fmt_args.push_back(fmt::arg("var_out", paramname + "_out"));
// imagine this were constructed by iterating over runtime-available data.
std::string argname = "dependent_param__var_out";
std::string argvalue = "dependent_param_out";
// Does not compile; fmt::arg expects char const *
fmt_args.push_back(fmt::arg(argname, argvalue));
return fmt_args;
}
int main() {
std::string fmtstring = "int {var_out} = function_call({var_in}, {dependent_param__var_out});\n";
auto args = construct_arg_store("foo");
fmt::vprint(fmtstring, args);
}
Right now, I build a symbol table from the dataset that contains std::string objects for all possible format arg names and use their .c_str() to build the fmt::arg objects (so that the generated C strings have a long enough lifetime). This works, but it seems like a bit of a dirty hack.
So I'm wondering, is there a better way to do it than that?
In general, it's better to use a template system like Mustache for this. That said, storing argument names as std::strings on the side and use them to construct dynamic_format_arg_store is OK. There is nothing hacky about it.

Cannot resolve type for template function

I'm trying to code up something very simple in D, but I'm having a few problems with one of the standard library template functions (specifically, nextPermutation from std.algorithm).
The crux of what I'm trying to do is to create all permutations of pandigital numbers (that is, numbers including all the values 1 to 9 exactly once).
To do this, I've done the following:
import std.algorithm;
import std.conv;
int[] pandigitals()
{
char[] initial = "123456789".dup;
auto pan = [to!int(initial)];
while(nextPermutation!(initial)) {
pan ~= to!int(initial);
}
return pan;
}
This gives me the error:
Error: cannot resolve type for nextPermutation!(initial)
I've also tried to explicitly set the types:
while(nextPermutation!("a<b", char[])(initial))
However, this gives an error saying it cannot match the template:
Error: template instance std.algorithm.nextPermutation!("a < b", char[]) does not match template declaration nextPermutation(alias less = "a < b", BidirectionalRange)(ref BidirectionalRange range) if (isBidirectionalRange!BidirectionalRange && hasSwappableElements!BidirectionalRange)
What is the correct form of the call meant to be?
Well, your first problem is that you're passing initial as a template argument instead of a function argument. The !() is for template arguments. so, instead of
while(nextPermutation!(initial))
you need to do
while(nextPermutation(initial)) {
Now, that will still give you an error.
q.d(10): Error: template std.algorithm.nextPermutation cannot deduce function from argument types !()(char[]), candidates are:
/usr/include/D/phobos/std/algorithm.d(12351): std.algorithm.nextPermutation(alias less = "a<b", BidirectionalRange)(ref BidirectionalRange range) if (isBidirectionalRange!BidirectionalRange && hasSwappableElements!BidirectionalRange)
And that's because hasSwappableElements!(char[]) is false, and per nextPermutations' template constraint it needs to be true for a type to work with nextPermutations.
It's false because all strings are treated as ranges of dchar rather than their actual element type. This is because in UTF-8 (char) and UTF-16 (wchar), there are multiple code units per code point, so operating on individual code units could break up a code point, whereas in UTF-32 (dchar), there's always one code unit per code point. Essentially, if arrays of char or wchar were treated as ranges of char or wchar, you'd run a high risk of breaking up characters so that you'd end up with pieces of characters rather than whole characters. So, in general in D, if you want to operate on an individual character, you should use dchar, not char or wchar. If you're not very familiar with Unicode, I'd suggest reading this article by Joel Spoelsky on the subject.
However, regardless of why hasSwappableElements!(char[]) is false, it is false, so you're going to need to use a different type. The simplest thing would probably be to just swap your algorithm over to using dchar[] instead.
int[] pandigitals()
{
dchar[] initial = "123456789"d.dup;
auto pan = [to!int(initial)];
while(nextPermutation(initial)) {
pan ~= to!int(initial);
}
return pan;
}

get the value of QuickFix::Field::OrdType?

I downloaded QuickFix.dll from quickfixengine.org
When I declare an object which belongs to namespace QuickFix::Fields, I cannot get its corresponding base value (I mean char value for OrdType, string value for OrderID etc). As there are no properties associated with them.
Is there any other way to achieve the same?
The code is:
......
QuickField::Fields::OrdType ordType;
message.Get(OrdType);//message is a NewOrderSingle
//type object defined prevviously in the code
//Now i wish to get the value contained in "ordType" but it has no
//properties to access its data member(s)
This is what you want to see:
QuickField::Fields::OrdType ordType;
message.get(ordType);
char char_value = ordType.getValue();
Advice: check out the class documentation. The field base class is FIX::FieldBase, which derives into FIX::StringField, FIX::BoolField, FIX::IntField, etc. All of these have a getValue() function which returns the raw field value converted into the proper data type.
Another way to do this (much less legitimate) is to use Message::getField(int) which returns the value of a field as a string. So you could use std::string str_value = message.get(40);, but you'd have a string instead of a char (or int or bool or whatever).

Idea working in types

Please see details in My previous question
1) cpf0.ml:
type string = char list
type name = string
type symbol =
| Symbol_name of name
2) problem.ml:
type symbol =
| Ident of Cpf0.string
In this problem.ml it has two definitions for type string, and surely it's giving me an error, but is it posible that I can make them have a same type? I need an idea.
module Str = struct type t = string end;;
module StrOrd = Ord.Make (Str);;
module StrSet = Set.Make (StrOrd);;
module StrMap = Map.Make (StrOrd);;
module SymbSet = Set.Make (SymbOrd);;
let rec ident_of_symbol = function
| Ident s -> s
let idents_of_symbols s =
SymbSet.fold (fun f s -> StrSet.add (ident_of_symbol f) s) s StrSet.empty;;
This expression has type Cpf0.string = char list but an expression was expected of type Util.StrSet.elt = string
You can use the name "string" for different types in different modules if you like, though (as Basile Starynkevitch points out) it's confusing. It would be better to pick a different name. If you really need to reuse the name, you can specify the module every time. If you don't specify a module, you'll get the predefined meaning (or the meaning from the innermost opened module).
It seems to me the problem in your quoted code is that this line:
module Str = struct type t = string end;;
doesn't specify a module name for string, so it refers to the predefined string. It seems possible you wanted to say:
module Str = struct type t = Cpf0.string end;;
It's hard to tell, however. There's not enough context for me to really understand what you're trying to do.
string is a predefined type in Ocaml (ie in the Pervasives module); it is e.g. the type of string literal constants like "this string". Use some other name (otherwise you, and any one reading your code, will be very confused)

Type casting in c++

In c++ can we cast an object to an integer ?
Clarifying my question - Suppose I have created an interface to handle file management task like create file, open file, read, write and I want to have one unique handle for every instance of a file. To achieve this can I create a file handle for each instance of the file interface by just type casting that instance to integer ?
To all - I hope now i am clear.
Not all objects. Every object in C++ has a type. That type of an object defines whether a cast to int exists, and if so, what algorithm is used.
If you have an object and want to cast it to int then you need to explicitly provide operator int for that class.
class File
{
public:
...
...
operator int() { return int(this); }
...
}
Then
File myFile;
int myFileHandle = myFile;
I would rather convert to a long type. This is safer when a pointer value is converted to an integral type on an x64 machine. You can just use reinterpret_cast<long>(myInterfacePointer) in that case.
you can, but it depend on the sizeof(YourObject) compared to sizeof(int), by casting any object to int you will access the first 4 bytes part of your object (assuming sizeof(int) == 4), if your object is smaller than sizeof(int) somewhere you will get access violation or crash. to cast :
`
MyObject object;
int castedObject = *((int*)&object);
`
to cast without pointer intermediate, you must provide typecast operator inside MyObject class. or you can declare global static function of int& operator=(const MyObject& object){...}
Edit: Since you are mapping files to a unique handle, you can use a std::vector<std::string> or a vector<shared_ptr<fstream> > or a vector<FILE*>.
On a POSIX-compliant system there is also fileno to convert a FILE* into its file descriptor which is an int.
To get the hash: Use the hash_value function from boost.
To convert any value to integer lexically: Use the lexical_cast<int> function from boost
To cast the value to integer: Just use (int)value.
For the above to work, the class you're going to convert needs to implement some special member functions e.g. operator<< and operator int.
To convert an object into an arbitrary unique integer, use (int)&value.
To get a random integer, use rand().
Why not just get the file descriptor/handle/whatever ID from the operating system and use that? Most systems have some kind of concept like that.
Consider using void * instead of int for the handles if you really want them to be pointers. Then casting a pointer-to-object to a handle is easy, and you can still hide the implementation away.
In response to #potatoswatter's comment to my first response.
I don't like the idea of casting objects. I would rather use a hashing function that produces an integer hash, say based on the filename or read/write flags. Now, I have to post another answer
class File
{
public:
...
...
operator int();
...
private:
char fileName[];
int flags;
};
The integer conversion operator is now a hashing function:
File::operator int()
{
int hash = 0;
int c;
char *str = fileName;
while (c = *str++)
hash += c;
hash += flags;
return hash;
}
I know the hash function is lousy. But you can avoid casts that are lousier and come up with your own hashing function that suits your needs better.