I'm working a small C++ JSON library to help sharpen my rusty C++ skills, and I'm having trouble understanding some behavior with initialization lists.
The core of the library is a variant class (named "var") that stores any of the various JSON datatypes (null, boolean, number, string, object, array).
The goal is for var to work as closely as possible to a JavaScript variable, so there's lots of operator overloading going on. The primitive datatypes are easy to take care of...
var fee = "something";
var fie = 123.45;
var foe = false;
The problem is with objects (maps) and arrays (vectors).
To get something close to a JavaScript object and array literal syntax, I'm using initialization lists. It looks like this:
// in my headers
typedef var object[][2];
typedef var array[];
// in user code
var foo = (array){ 1, "b", true };
var bar = (object){ { "name", "Bob" }, { "age", 42 } };
This works out pretty nicely. The problem comes in with nested lists.
var foo = (array){ 1, "b", (array){ 3.1, 3.2 } };
For some reason my variant class interprets the nested "array" as a boolean, giving:
[1, "b", true]
Instead of:
[1, "b", [3.1, 3.2]]
If I explicitly cast the inner list to a var, it works:
var foo = (array){ 1, "b", (var)(array){ 3.1, 3.2 } };
Why do I have to explicitly cast the inner list to a var after I cast it to an array, and how can I get around this extra cast? As far as I can tell it should be implicitly converting the array to my var class anyway, since it's using the constructor for an array of vars:
template <size_t length>
var(const var(&start)[length]) {
// internal stuff
init();
setFromArray(vector<var>(start, start + length));
}
It seems that without the explicit cast to var, the initialization list somehow gets cast to something else on its way from being cast from an array to a var. I'm trying to understand why this happens, and how to avoid it.
Here's a gist with the complete source. Let me know if I should add anything relevant to the question.
Update
Apparently (foo){1, "two"} does not actually cast an initialiation list; it's a complete expression called a compound literal. It seems that it's only available in C, although g++ doesn't complain unless you give it -pedantic.
It looks like my options are:
Find another concise initialization syntax that is officially supported.
Use compound literals and hope they work in other compilers.
Drop support for C++ < 11 and use initializer_list.
Don't offer a concise initialization syntax.
Any help with the first option would be the sort of answer I'm looking for at this point.
Macros are another sort of last-ditch option, and I've written some that do the job, but I'd like to not have to use them.
You need to use the facilities already provided to you by Boost.
typedef boost::optional<boost::make_recursive_variant<
float, int, bool, //.. etc
std::unordered_map<std::string, boost::optional<boost::recursive_variant_>>,
std::vector<boost::recursive_variant_>
> JSONType;
They can easily define recursive variant types.
Related
I have a base class and I want to store instances of its derivatives in a collection of some sort.
At first I created a map:
std::map<int, Variable> varriableItems;
and then ussing templates I created functions for each derivative and I tried passing in the derivatives like so:
template <>
void Array::addToMap<Number>(Number input)
{
numberVariables[itemCount_] = input;
itemCount_++;
}
By doing so this function was not called because everything was of type Variable of course and I found out about slicing.
So instead I changed my map to take in pointers to my base class
std::map<int, Variable*> varriableItems;
but the problem I have is that all my objects are not created as pointers so I could not pass them in and I was getting errors.
No suitable conversion from "Number" to "Variable" exists.
Due to my implementation I can only create instances of objects
like so:
auto aNumberVariable = Number{50};
Ofcourse if I instead do:
Number aNumberVariable = new Number(50);
it works great.
The reason am doing this is explained bellow.
Please bear with me because this is a weird assignment.
We were asked to create a program that behaves/understands the syntax of a programming language called Logo, without actually analyzing the text as an input file, but rather "disguise" it to appear as such while in fact we just use C++ using what we learned from C++ and lots of overloads and pre-processor tricks
We have to be able to make our own "types" of variables called NUMBER,WORD,BOOLEAN,ARRAY, LIST,SENTENCE.
To declare them we have to use(note no semi-colons should be used):
//define number variable with value 21
MAKE number = NUMBER: 21
//define hello variable with value “hello”
MAKE hello = WORD: “hello”
//define myMoves variable contains list of turtle moves
MAKE myMoves = LIST [
LIST [WORD: “FORWARD”, NUMBER: 100],
LIST [WORD: “LEFT”, NUMBER: 90],
LIST [WORD: “FORWARD”, NUMBER: 100]
]
//define array variable with empty array
MAKE array = ARRAY {
number,
hello,
NUMBER: 12
BOOLEAN: TRUE,
ARRAY {
myMoves,
LIST [WORD: “BACK”, NUMBER: 100]
}
}
//define book variable with sentence type
MAKE book = SENTENCE (hello, WORD: “hello!”)
That's just a small part, we later have to support functions, nested loops , etc.
So do this I have to find a way to use the colon since I cannot overload it, so I did this:
//Create an instance of Number and write the first half of the ternary operator so we
//always get the false value so we can use the : like this
#define NUMBER Number{} = (false) ? 0
//semicolon infront for the previous command that needs it
#define MAKE ;auto
So now this:
//following commands will deal with the semicolon
MAKE myNumber = NUMBER: 21
worked great and it actually gets replaced by the processor to this:
auto myNumber = Number{} = (false) ? 0 : 21
So i worked with this for all my derivatives and I proceeded to overload operators to compare them, implement if else function in a similarly weird syntax.
Now I either have to figure out a way to make this work again but this time creating them as pointer instead (Which I assume is the only way for this to work, but I so far I couldn't figure it out) or create a single class for all types but doing it in separate objects that all inherit from a single base class makes more sense to me.
And am not sure how strict they will be, it is an unconventional project assignment for sure.
The reason I want to hold them together in a container is so I can then implement an Array and list object that can hold every type. At first I tried to use a different container for each type and made an iterator to iterate multiple maps separately, but when I got to the LIST implementation things got weird.
The list syntax is using the brackets [ ] which can only get 1 input value, so the idea was to collect them by overloading the comma operator and pass in one value to the list object.
I know this is weird , thank you for your time
I didn't read through all of your post. (actually I did because your task is so ... beyond words) but if you need polymorphism in a container and you also need the container to hold the objects, then the solution is unique_ptr:
container<std::unique_ptr<Base>>
In your case it would go something along this:
std::unordered_map<int, std::unique_ptr<Variable>> varriableItems;
varriableItems[0] = std::make_unique<Number>(50);
Wanted to toy with adding some sugar in Swift3. Basically, I wanted to be able to do something like:
let randomAdjust = (-10...10).random
To do that, I decided I would need to extend ClosedRange. But then found it would probably be even better for my case, I really just plan on doing Int's for now, to use CountableClosedRange. My latest of multiple attempts looked like:
extension CountableClosedRange where Bound == Int {
var random:Int {
return Int(arc4random_uniform(UInt32(self.count) + 1)) + self.lowerBound
}
}
But the playground complains:
error: same-type requirement makes generic parameter 'Bound' non-generic
extension CountableClosedRange where Bound == Int {
I don't even know what it's telling me there.
The way this roadblock is commonly encountered is when attempting to extend Array. This is legal:
extension Array where Element : Comparable {
}
But this is illegal:
extension Array where Element == Int {
}
The compiler complains:
Same-type requirement makes generic parameter 'Element' non-generic
The problem is the use of == here in combination with Array's parameterized type Element, because Array is a generic struct.
One workaround with Array is to rise up the hierarchy of Array's inheritance to reach something that is not a generic struct:
extension Sequence where Iterator.Element == Int {
}
That's legal because Sequence and Iterator are generic protocols.
Another solution, though, is to rise up the hierarchy from the target type, namely Int. If we can find a protocol to which Int conforms, then we can use the : operator instead of ==. Well, there is one:
extension CountableClosedRange where Bound : Integer {
}
That's the real difference between our two attempts to implement random on a range. The reason your attempt hits a roadblock and mine doesn't is that you are using == whereas I am using :. I can do that because there's a protocol (FloatingPoint) to which Double conforms.
But, as you've been told, with luck all this trickery will soon be a thing of the past.
In Swift 4, what you are attempting is now completely supported. Hooray!
extension Stack where Element: Equatable {
func isTop(_ item: Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
Example from Swift docs: https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID553
I'm working on a shift/reduce parser generator in C++11 and I am not sure how to specify the interface type of the input productions and reduction action functions such that they will hold the information I want to put in them.
I want to specify the grammar statically but using C++ types (not a separate build tool).
For each symbol (terminals and non-terminals) the user provides a string name and a type.
Then each production specifies a head symbol name and one or more body symbol names.
For each production an action function is provided by the user (the hard part) that returns the head nonterminal type and has parameters corresponding to the production body symbols (of their corresponding types).
The main problem is statically binding the parameter types and return type of these action functions to the corresponding symbol types
So for example:
Suppose we have nonterminals X, A B C
Their names/types might be:
"X" Foo
"A" string
"B" string
"C" int
And in the grammar there might be a production:
X -> A B C
And there will be an action function provided by the user for that production:
Foo f(string A, string B, int C)
If that production is reduced than the function f should be called with the production body parameters. The value returned by f is then stored for when that symbol is used in a higher up reduction.
So to specify the grammar to the parser generator I need to provide something like:
(I know the following is invalid)
struct Symbol
{
string name;
type T;
}
struct Production
{
string head;
vector<string> body;
function<head.T(body[0].T, body[1].T, ..., body[n].T)> action;
}
struct Grammar
{
vector<Symbol> symbols;
vector<Production> productions;
}
And to specify the earlier example would be:
Grammar example =
{
// symbols
{
{ "X", Foo },
{ "A", string },
{ "B", string },
{ "C", int }
},
// productions
{
{
"X",
{ "A", "B", "C" },
[](string A, string B, int C) { ... return Foo(...); }
}
}
}
This won't work of course, you can't mix type parameters with runtime parameters like that.
One solution would be to have some generic base:
struct SymbolBase
{
...
}
template<class SymbolType>
struct SymbolDerived<SymbolType> : SymbolBase
{
SymbolType value;
}
and then make all action functions of type:
typedef function<SymbolBase(vector<SymbolBase>)> ActionFunction;
and sort it out at runtime. But this makes usage more difficult, and all the casting is slow. I'd rather have the function signatures checked at compile-time and keep the mechanics hidden from the user.
How can I restructure the Symbol, Production and Grammar types to carry the information I am trying to convey in legal C++11?
(Yes I have looked at Boost Spirit and friends, it is a fine framework but it is recursive descent so the languages it can handle in a single pass are fewer than a LALR parser and because it uses backtracking the reduction actions will get called multiple times, etc, etc)
I've been playing around with precisely this problem. Once possibility I've been looking at, which looks like it should work, is to use a stack of variant objects, perhaps boost::variant or boost::any. Since each reduction knows what it's expecting from the stack, the access will be type-safe; unfortunately, the type-check will be at run-time, but it should be very cheap. This has the advantage of catching bugs :) and it will also correctly destruct objects as they're popped from the stack.
I threw together some sample code as a PoC, available upon request. The basic style for writing a reduction rule is something like this:
parse.reduce<Expression(Expression, _, Expression)>
( [](Expression left, Expression right){
return BinaryOperation(Operator::Times, left, right);
});
which corresponds to the rule:
expression: expression TIMES expression
Here, BinaryOperation is the AST node-type, and must be convertible to Expression; the template argument Expression(Expression, _, Expression) is exactly the left-hand-side and right-hand-side of the production, expressed as types. (Because the second RHS type is _, the templates don't bother feeding the value to the reduction rule: with a proper parser generator, there would actually be no reason to even push punctuation tokens onto the stack in the first place.) I implemented both the tagged union Expression and the tagged type of the parser stack using boost::variant. In case you try this, it's worth knowing that using a variant as one of the option types of another variant doesn't really work. In the end, it was easiest to wrap the smaller union as a struct. You also really have to read the section about recursive types.
I am developing GUI application via wxWidgets. It has 2 parts: GUI part and "Logic" part. I want to have Logic part totally independent on wxWidgets. But one component in the GUI returning wxVariant and I need to use it in the Logic part.
So I am looking for a way to "convert" wxVariant to boost::variant
wxVariant works like this:
wxVariant v("37");
int i = v.GetInteger(); //i==37
So I am thinking something like
string s = methodReturningWxVariant().GetString();
boost::variant bV(s);
//later in code e.g
bV.GetInt();
bV.GetBool();
Is it possible to use boost::Variant (or boost::Any) like this?
You can probably use boost::variant with some changes. To start with, you need to tell boost::variant which types it will be storing:
boost::variant<int, string, bool> v;
Since you probably will be using this type in a few places, you will probably want to create an alias for it. i.e.
typedef boost::variant<int, string, bool> myvar;
then you can use myvar directly:
myvar x = "hello";
myvar y = 20;
myvar z = false;
to retrieve values:
string s = boost::get<string>(x);
int i = boost::get<int>(y);
bool b = boost::get<bool>(z);
If you attempt to get a different type than is stored in the variant, it will throw an exception.
You can query the variant's type with the which() member function. It will return a 0-based index to the type the variant is currently holding.
switch (x.which()) {
case 0: // it's an int
case 1: // it's a string
case 2: // it's a bool
}
Simple answer? No. You cannot convert via strings, this induces a loss of information and boost::variant does not automatically attempt to parse strings.
I don’t know whether wxVariant offers an explicit conversion – in general, it may be difficult to convert to boost::variant without testing for special cases.
boost::variant (please don't capitalize 'v') works another way: you can only get back what you put inside. Think about it as a type-safe(r) union.
Checking documenation and tutorial also won't hurt.
Boost.Any library doesn't differ from Boost.Variant in this respect (what you put is what you get :) ), but boost::any is unbounded: you can store value of any type in boost::any, but in boost::variant you can only store what was declared by variant's template parameters.
boost::variant does not do conversion for you. There are other separate means to convert a string to an integer, such as strtol(), sscanf(), boost::lexical_cast<>()...
I am having problems translating C++ data structures to Scala. Scala is really different from C++, but I like a lot of it.
I have the following Code fragment in C++:
struct Output
{
double point;
double solution[6];
};
struct Coeff
{
double rcont1[6];
double rcont2[6];
double rcont3[6];
double rcont4[6];
double rcont5[6];
double rcont6[6];
};
std::list<Output> output;
std::list<Coeff> coeff;
I now fill the list in a while loop with data
while(n<nmax) {
if step successfull
Output out;
out.point = some values;
out.solution[0] = some value;
output.push_back(out);
}
I tried creating a simple class in Scala to hold the data.
class Output
{
var point: Double
var solution: Array[Double] = new Array(6)
}
But this doens't work since point is not initialized. Is there a way around this? I just want to define the variable but not initialize it.
Another quick thing. I am looking for an equivalent to stl::lower_bound.
Is finds the right position to insert an element in an sorted container to maintain the order.
Thanks for helping a Scala beginner
Why don't you want to initialize it? For efficiency? I'm afraid that the JVM doesn't let you get away with having random junk in your variables based on whatever was there originally. So since you have to initialize it anyway, why not specify what your "uninitialized" value is?
class Output {
var point = 0.0
var solution = new Array[Double](6)
}
(You could use Double.NaN and check for point.isNaN if you later need to see whether the value has been initialized or not.)
You could use _ as the default initialization, but unless you use it in generic code:
class Holder[T] {
var held: T = _
}
then you're just obscuring what the value really will be set to. (Or you are announcing "I really don't care what goes here, it could be anything"--which could be useful.)
I just found the answer to the intialistion:
class Output
{
var point: Double = _
var solution: Array[Double] = Array(6)
}
Puh Scala has a lot of syntx to get used to :-)
Anyone have a solution for the lower_bound equivalent ?
It's hard to translate effectively, as you've left a lot of unknowns hidden behind pseudo code, but I'd advocate something along these lines:
// type alias
type Coeff = Seq[Seq[Double]]
// parameters passed to a case class become member fields
case class Output (point: Double, solution: Seq[Double])
val outputs = (0 to nmax) map { n =>
Output(generatePoint(n), generateSolution(n))
}
If you can flesh out your sample code a bit more fully, I'll be able to give a better translation.