How to construct llvm::Align from LogValue? - llvm

I want to construct llvm::Align from Log2Value(2^N), which is a private structure of llvm::Align, so the constructor constexpr llvm::Align::Align(LogValue CA) cannot be called, it will call llvm::Align::Align(uint64_t Value).
The method I found is
llvm::Align fromLog2(uint64_t shift) {
return llvm::Align(uint64_t(1) << shift);
}
Any idea?

Related

Constructor Initializer List vs Constructor Body

Let's say someString initialization is a tad complicated, hence we write a simple member function stringInitialization() with which to initialize someString in the body of the constructor:
class DemoL {
private:
int someNumber;
std::string someString;
void stringInitialization() {
if (someNumber == 1) {
someString = "FIRSTSTRING";
} else if (someNumber == 2) {
someString = "SECONDSTRING";
} else {
someString = "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber) {
stringInitialization();
}
};
This way, I'd assume, someString will be default initialized before the body of the constructor and only after that will it be modified by calling stringInitialization().
So, let's modify the code a bit, so that we initialize someString in the constructor initializer list:
class DemoL {
private:
int someNumber;
std::string someString;
std::string stringInitialization() const {
if (someNumber == 1) {
return "FIRSTSTRING";
} else if (someNumber == 2) {
return "SECONDSTRING";
} else {
return "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber),
someString(stringInitialization()) {}
};
Would you be so kind as to tell me whether the second variant is more efficient and correct?
Your assumption is correct. The constructor DemoL(int rNumber) needs to be able to default construct the member someString and this is no problem because std::string is default constructible.
One obvious point is that one member could be not default-constructible, in which case you would have to initialize it.
But even if it is, default constructing it could be a waste of resources, if you are changing it right after, so the second alternative seems better to me as it goes straight to the point.
However, since stringInitialization returns by value, I would use std::move, no, this is actually a bad idea, as pointed out in the comments.
So as a conclusion:
the two codes are the same as regards someNumber
the first code default-initializes someString ("calls" std::basic_string<...>::basic_string) and then assigns it (calls std::basic_string<...>::operator=)
the second code constructs the return std::string value from the sting literals when the call to stringInitialization returns (calls basic_string<...>::basic_string(const char*)), and then copy-constructs someString (calls basic_string<...>::basic_string(basic_string&&)); actually copy elision happens because stringInitialization returns an rvalue.

constructor without initializer list having objects with deleted constructors

I used to have my CameraMill class check if the size of the input params vector is correct and then initialize my cameras m_cam0 and m_cam1
CameraMill::CameraMill(std::vector<camera::Params> params)
{
if (params.size() == 2)
{
m_cam0 = Camera(params[0]);
m_cam1 = Camera(params[1]);
}
}
A recent change to the Camera class has deleted the constructor. So this fails with error: use of deleted function. I could initialize them in the initializer list but then I can't check the size...
CameraMill(std::vector<Params> params)
: m_cam0(params[0])
, m_cam1(params[1])
{
// if (params.size() == 2)
// {
// m_cam0 = Camera(params[0]);
// m_cam1 = Camera(params[1]);
// }
}
How do I go about without using initializer list?
You can use a helper function to get the right Param object.
CameraMill(std::vector<Params> params) :
m_cam0(CameraMill::getParam(params, 0)),
m_cam1(CameraMill::getParam(params, 1))
{
}
where
Params const& CameraMill::getParam(std::vector<Params> const& params, size_t i)
{
return (i < params.size()) ? params[i] : Params();
}
Update
The above function results in undefined behavior. The temporary is destroyed at the end of the function call. Thanks, #Jarod42.
Other options:
Make the return type an object instead of a reference.
Params CameraMill::getParam(std::vector<Params> const& params, size_t i)
{
return (i < params.size()) ? params[i] : Params();
}
Have a function static variable and return it instead of a default constructed temporary object.
Params const& CameraMill::getParam(std::vector<Params> const& params, size_t i)
{
static Params p;
return (i < params.size()) ? params[i] : p;
}
I could initialize them in the initializer list but then I can't check the size...
A workaround would be to call a function in the initializer list to perform the check and/or construct the objects, although that usually looks quite bad.
It would be simpler to simply call .at() instead, and then inside the body of the constructor check if the size was bad to begin with:
CameraMill(std::vector<Params> params)
: m_cam0(params.at(0))
, m_cam1(params.at(1))
{
if (params.size() != 2)
...
}
Not a great solution either, but works.
The best, of course, is to either fix your constructor signature, revert the Camera class, or simply setup the m_cam objects after creating them "empty" (assuming you have a constructor for that).

How to overload the operators to call a setter function on an operator[] call?

How can I overload the operators of a class, so that using syntax of
classInstance[index] = value;
performs
classInstance.cfgfile.Write(index,value)
background info; feel free to skip.
The application we develop uses a memory-mapped access to a segment of NVRAM - actually, mapped are just two registers, address and data. You write to the address register, then either write or read the data register. After initialization, the reads and writes are performed by a simple [] overload of the class holding the reference to the segment of memory. You refer to the instance's [] giving a namespaced index of the cell you want to read and write and it does its thing.
int& IndirectMemory::operator[](RTCMemIndex idx)
{
*midx_reg = idx;
return *mdata_reg;
}
(code stripped of irrelevant elements like mutexes and sanity checks).
Everything works fine... as long as the NVRAM works fine. This specific chip is out of production, and the ones 'out in the wild' began dying of old age currently. Their functionality is of low significance to our use, and we could shift their role to the flash memory with nearly no impact (just a little more flash wear) if the chip goes corrupt. Thing is we want to use the flash record using our config format, which uses getters and setters.
int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);
And in many places of the code we have calls to NVRAM through IndirectMemory[Some_Register] = Some_Value; writting assorted things that change frequently and we want to persist through reboot. I'd like to retain this syntax and behavior, but be able to write to the file if NVRAM is detected to be corrupted or manually disabled through a config entry.
The net is rife with examples of using operator[] for setting given value just by returning the reference to it. For example:
unsigned long operator [](int i) const {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}
In that case if I call, say, reg[3] = 1; the [] will return a reference to the element#3 and the default operator= will write to the reference just fine.
But since I can't return a reference to a key in the file (.WriteKey() just performs a complete write, returning success or error), and operator= doesn't take an index, I'm afraid this simple option won't help.
You can use a proxy class to solve this. Since value can't be passed into classInstance we need to make an object that operator[] can return that will get the value of value and knows which instance to apply the operation to. Using
struct Proxy
{
classInstance_type& to_apply;
index_type index;
Proxy(classInstance_type& to_apply, index_type index) : to_apply(to_apply), index(index) {}
Proxy& operator=(value_type const & value)
{
to_apply.cfgfile.Write(index,value)
return *this;
}
};
your class's operator[] would look like
Proxy operator[](index_type index)
{
return Proxy{*this, index};
}
and then when you do classInstance[index] = value; you call Proxy's operator= which has a reference to the object to call, the index to use, and the value you also need.
You can also do this without a proxy class. You can make operator[] return a reference to *this and than overload the = operator of said class to perform Write on whatever was given to operator= in the second argument.
#include <iostream>
struct Foo {
void Write(int idx, int value) {
std::cout << "Write(" << idx << ", " << value << ")\n";
}
Foo& operator[](int idx) {
this->index = idx;
return *this;
}
void operator=(int value) {
this->Write(this->index, value);
}
int index;
};
int main() {
Foo f;
f[5] = 10;
}
Prints: Write(5, 10)

How do I change the map container's internal sorting scheme?

I'm a beginner C++ programmer so there are language constructs that I don't understand which prevents me from understanding map's API (for your reference, here)
More to the point, some questions:
How do I change the internal sorting scheme of map so that, given that we're working with map::<string, ...>, the key values are sorted alphabetically?
More specifically about the map::key_comp, is it a define-and-forget thing where once we define what it means for two elements of the same type to be "unequal (one is less than the other)", then the sorting is done internally and automatically - so all we need to is insert key/value pairs? Or do we have to define equality/ordering and then call the function explicitly to return a boolean to implement ordered insertion?
Here's an example of how you give the sorted map a template argument to use a non-default sort:
std::map<int, int, std::greater<int> > m;
Taken from C++ std::map items in descending order of keys
Also, for a more complex example: how to declare custom sort function on std::map declaration?
[Solved] Solution I'd chosen
Suppose your map was: map<int,vector<int>,compAB> myMap;
Then you need to do 2 things to define "compAB":
Define a comparison function that returns true or false/(or 1 or 0). I haven't tested whether this function can take multiple arguments (although I don't see why it can't so long as it returns a bool. This function should specify how you intend to order two objects of the same type as the key value in your your map.
bool compare(int a, int b)
{
if(a < b) return true;
return false; //Default
}
The API for the map::key_comp object (here indicates that the comparison function needs to return true if the first argument is "less than"/"comes before" the second argument. It should return false otherwise source). Here, I've used a simple criteria for determining "less than": a precedes b if a<b, as the computer evaluates it.
Create a struct whose member consist of just an operator-overload:
struct compAB
{
bool operator()(int i1, int i2){
return compare(i1, i2);
}
};
Then, you can make the declaration: map<int,vector<int>,compAB> myMap; and any calls to insertion() will insert the pairs you've indicated according to the key-ordering scheme you specified
For instance:
#include <iostream>
#include <map>
bool compare_descend(int a, int b)
{
//specifies that when a>b return true -> a FOLLOWS b
if(b < a) return true;
return false;
}
bool compare_ascend(int a, int b)
{
//specifies that when a<b return true -> a PRECEDES b
if(a < b) return true;
return false; //Default
}
struct comp_asc
{
bool operator()(int i1, int i2)
{
return compare_ascend(i1, i2);
}
};
int main()
{
std::cout << "int_map_asc: [key,value]\n";
//Map declaration via class function
std::map<int,std::string,comp_asc> int_map_asc;
//Insert pairs into the map
int_map_asc.insert( std::pair<int,std::string>(0, "Alan") );
int_map_asc.insert( std::pair<int,std::string>(1, "Baye") );
int_map_asc.insert( std::pair<int,std::string>(2, "Carl") );
int_map_asc.insert( std::pair<int,std::string>(3, "David") );
//Iterate & print
std::map<int,std::string,comp_asc>::iterator a_it;
for(a_it=int_map_asc.begin(); a_it!=int_map_asc.end(); a_it++)
std::cout << "[" << a_it->first << "," << a_it->second << "]\n";
std::cout << "\nint_map_desc: [key,value]\n";
//Map declaration via function pointer as compare
bool(*fn_compare_desc)(int,int) = compare_descend; //Create function ptr to compare_descend()
std::map<int,std::string,bool(*)(int,int)> int_map_desc(fn_compare_desc); //fn ptr passed to constructor
//Insert pairs into the map
int_map_desc.insert( std::pair<int,std::string>(0, "Alan") );
int_map_desc.insert( std::pair<int,std::string>(1, "Baye") );
int_map_desc.insert( std::pair<int,std::string>(2, "Carl") );
int_map_desc.insert( std::pair<int,std::string>(3, "David") );
//Ititerate & print
std::map<int,std::string,bool(*)(int,int)>::iterator d_it;
for(d_it=int_map_desc.begin(); d_it!=int_map_desc.end(); d_it++)
std::cout << "[" << d_it->first << "," << d_it->second << "]\n";
return 0;
}
Output:
int_map_asc: [key,value]
[0,Alan]
[1,Baye]
[2,Carl]
[3,David]
int_map_desc: [key,value]
[3,David]
[2,Carl]
[1,Baye]
[0,Alan]
Additional examples here.

Simple C++ getter/setters

Lately I'm writing my getter and setters as (note: real classes do more things in getter/setter):
struct A {
const int& value() const { return value_; } // getter
int& value() { return value_; } // getter/setter
private:
int value_;
};
which allows me to do the following:
auto a = A{2}; // non-const object a
// create copies by "default" (value always returns a ref!):
int b = a.value(); // b = 2, is a copy of value :)
auto c = a.value(); // c = 2, is a copy of value :)
// create references explicitly:
auto& d = a.value(); // d is a ref to a.value_ :)
decltype(a.value()) e = a.value(); // e is a ref to a.value_ :)
a.value() = 3; // sets a.value_ = 3 :)
cout << b << " " << c << " " << d << " " << e << endl; // 2 2 3 3
const auto ca = A{1};
const auto& f = ca.value(); // f is a const ref to ca.value_ :)
auto& g = ca.value(); // no compiler error! :(
// g = 4; // compiler error :)
decltype(ca.value()) h = ca.value(); // h is a const ref to ca.value_ :)
//ca.value() = 2; // compiler error! :)
cout << f << " " << g << " " << h << endl; // 1 1 1
This approach doesn't allow me to:
validate the input for the setter (which is a big BUT),
return by value in the const member function (because I want the compiler to catch assignment to const objects: ca.value() = 2). Update: see cluracan answer below.
However, I'm still using this a lot because
most of the time I don't need that,
this allows me to decouple the implementation details of my classes from their interface, which is just what I want.
Example:
struct A {
const int& value(const std::size_t i) const { return values_[i]; }
int& value(const std::size_t i) { return values_[i]; }
private:
std::vector<int> values_;
// Storing the values in a vector/list/etc is an implementation detail.
// - I can validate the index, but not the value :(
// - I can change the type of values, without affecting clients :)
};
Now to the questions:
Are there any other disadvantages of this approach that I'm failing to see?
Why do people prefer:
getter/setters methods with different names?
passing the value as a parameter?
just for validating input or are there any other main reasons?
Generally using accessors/mutators at all is a design smell that your class public interface is incomplete. Typically speaking you want a useful public interface that provides meaningful functionality rather than simply get/set (which is just one or two steps better than we were in C with structs and functions). Every time you want to write a mutator, and many times you want to write an accessor first just take a step back and ask yourself "do I *really* need this?".
Just idiom-wise people may not be prepared to expect such a function so it will increase a maintainer's time to grok your code.
The same-named methods are almost the same as the public member: just use a public member in that case. When the methods do two different things, name them two different things.
The "mutator" returning by non-const reference would allow for a wide variety of aliasing problems where someone stashes off an alias to the member, relying on it to exist later. By using a separate setter function you prevent people from aliasing to your private data.
This approach doesn't allow me to:
return by value in the const member function (because I want the compiler to catch assignment to const objects ca.value() = 2).
I don't get what you mean. If you mean what I think you mean - you're going to be pleasantly surprised :) Just try to have the const member return by value and see if you can do ca.value()=2...
But my main question, if you want some kind of input validation, why not use a dedicated setter and a dedicated getter
struct A {
int value() const { return value_; } // getter
void value(int v) { value_=v; } // setter
private:
int value_;
};
It will even reduce the amount typing! (by one '=') when you set. The only downside to this is that you can't pass the value by reference to a function that modifies it.
Regarding your second example after the edit, with the vector - using your getter/setter makes even more sense than your original example as you want to give access to the values (allow the user to change the values) but NOT to the vector (you don't want the user to be able to change the size of the vector).
So even though in the first example I really would recommend making the member public, in the second one it is clearly not an option, and using this form of getters / setters really is a good option if no input validation is needed.
Also, when I have classes like your second type (with the vector) I like giving access to the begin and end iterators. This allows more flexibility of using the data with standard tools (while still not allowing the user to change the vector size, and allowing easy change in container type)
Another bonus to this is that random access iterators have an operator[] (like pointers) so you can do
vector<int>::iterator A::value_begin() {return values_.begin();}
vector<int>::const_iterator A::value_begin()const{return values_.begin();}
...
a.value_begin()[252]=3;
int b=a.value_begin()[4];
vector<int> c(a.value_begin(),a.value_end())
(although it maybe ugly enough that you'd still want your getters/setters in addition to this)
REGARDING INPUT VALIDATION:
In your example, the assignment happens in the calling code. If you want to validate user input, you need to pass the value to be validated into your struct object. This means you need to use member functions (methods). For example,
struct A {
// getter
int& getValue() const { return value_; }
// setter
void setValue(const int& value) {
// validate value here
value_ = value;
}
private:
int value_;
};
By the way, .NET properties are implemented are methods under the hood.