-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Tony Van Eerd edited this page Nov 28, 2019
·
4 revisions
A place to put random bits of code.
- StrongId
- Unit
- Radians/Degrees
- sample()
A template for making ID types that are unique types for unique uses. ie WidgetIds are not the same as EmployeeIds, and it is nice if the compiler prevents you from mixing one with the other.
class Cat { /*...*/ };
class Dog { /*...*/ };
using CatId = StrongId<std::string, Cat>;
using DogId = StrongId<std::string, Dog>;
void petDog(DogId dogToPet);
void incompatibleTypes()
{
CatId mycat("whiskers");
// this next line will give a compiler error
// error: could not convert 'mycat'
// from 'StrongId<[...],Cat>' to 'StrongId<[...],Dog>'
petDog(mycat);
}
using Apples = Unit<int, struct ApplesTag>;
using Oranges = Unit<int, struct OrangesTag>;
Apples apples(17);
Oranges oranges(17);
apples == oranges; // does not compile - can't compare Apples and Oranges
// also can't add them, multiply them, etc
// but can scale them:
apples = apples * 3; // 3 times as many apples!
// and add, etc
apples = apples + apples; // moar apples
int f(Apples);
int x = f(17); // doesn't compile - no conversion
int y = f(oranges); // doesn't compile - no conversion
Built from Unit!
Note you never need to overload on Radians/Degrees, just pick one, and the other "just works":
void setLaunchAngle(Radians angle);
Radians calcLaunchAngle();
void f()
{
// this function works in Degrees,
// and doesn't care what calcLaunchAngle and setLaunchAngle work with
Degrees angle = calcLaunchAngle();
if (closeTo(angle, 90))
ask("Almost straight up; what goes up must come down. Are you sure?");
setLaunchAngle(angle);
}
Similar to C++17 std::sample()
but I don't have C++17 yet. And I like the out()
function better than an output iterator.
This is one of the functions in sample.h, but it also is an example of how to use the generic sample(beg,end,count,urng,out)
function.
template<typename T, typename Transform>
std::vector<T> sample(std::vector<T> const & in, int count, Transform const & trans)
{
std::vector<T> out;
if (in.size() < count)
out = in;
else {
std::random_device rd;
std::mt19937 gen(rd());
out.reserve(count);
sample(in.begin(), in.end(), count, gen,
[&trans, &out](T const & elem) { out.push_back(trans(elem)); });
}
return out;
}
And then how to use the nice and easy version:
float estimateThreshold(std::vector<float> const & errors)
{
const int maxSamples = 30000;
std::vector<float> absErrs = sample(errors, maxSamples, [](float val){return abs(val);});
... do stuff with sample ...
}