char and initializer lists - g++

I'd like to pass some numeric byte values via an initializer list a variadic template into an array. Is that possible?
template < int N > struct a {
char s[N];
template < typename ... A >
a (A ... _a) : s {_a...} {}
};
int main () {
// g++-4.5: error: narrowing conversion of »_a#0« from »int« to »char« inside { }
a < 3 > x { 1, 2, 3 };
}
What I can think of is
to use octal representation, '\001' etc., or
to cast every single value.
But both is not satisfying.

You don't need any complicated code
template < int N > struct a {
char s[N];
template < typename ... A >
a (A ... _a) : s {static_cast<char>(_a)...} {}
};

NOTE: All of this is unnecessary unless you have added functionality to the class so it's no longer an aggregate. (For example, other constructors, private members, a base class, etc.) The immediate way to fix the code in the question is simply to remove the constructor. So, let's assume there's something more to it.
I've seen some people trying to do things like this. It seems ugly, dealing with conversion semantics and trying to artificially re-create the functionality of a usual function call.
Here is a strategy to create an array class that simply has the right constructor in the first place.
Template aliasing would put the icing on the cake by hiding the ::type ugliness, but it's not in GCC yet.
template< typename ... NT >
struct var_ctor_array {
enum { size_e = 0 }; // only used for zero size case
};
template< typename T, typename ... NT >
struct var_ctor_array< T, NT ... > {
enum { size_e = 1 + sizeof...( NT ) };
T st[ size_e ];
var_ctor_array( T elem0, NT ... elemN )
: st { elem0, elemN ... } {}
};
template< typename T, size_t N, typename ... NT >
struct gen_var_ctor_array {
typedef typename gen_var_ctor_array< T, N-1, T, NT ... >::type type;
};
template< typename T, typename ... NT >
struct gen_var_ctor_array< T, 0, NT ... > {
typedef var_ctor_array< NT ... > type;
};
int main() { // usage
gen_var_ctor_array< char, 5 >::type five( 1, 2, 3, 4, 5 );
}

You're not actually using initializer lists. The constructor receives a variadic template and you initialize x with uniform initialization.
The only problem is I don't know of an elegant way of initializing an array with an initializer_list, AFAIK std::array should have a constructor that accepts initializer_list but it doesn't seem to be supported by g++ yet.
#include <utility>
template < int N > struct a {
char s[N];
a (std::initializer_list<char> list) {
if (N != list.size())
throw "list wrong size";
int i = 0;
const char* p = list.begin();
while(p != list.end())
s[i++] = *p++;
}
};

Related

gtest expected args in mock method

I have mocked a function which takes std::set (stl) as an argument and I expected it to be called with the right args. std::set is a set of user-defined struct and I just want to verify one field of that struct to have one value for all the member of the set.
ie
struct my_struct {
int i;
int j;
int k;
}
using my_set = std::set<my_struct>;
MOCK_METHOD(void, my_func, (my_set));
EXPECT_CALL(obj, my_func(_))
.Times(1);
Now I want to expect my_func to be called with my_set and each member of my_set is my_struct and my_struct.i should be 1 for all the members.
I understand it could be done with Matcher and Each but now sure how to do that as I run into compilation error
The key is to use ::testing::Each matcher with ::testing::Field matcher combined. Each iterates over all elements of the container argument and Field matcher allows you to set proper expectations on the user-defined struct fields. Complete example:
struct my_struct {
int i;
int j;
int k;
};
auto my_set_comp = [](const auto& l, const auto& r) { return std::tie(l.i, l.j, l.k) < std::tie(r.i, r.j, r.k); };
using my_set = std::set<my_struct, decltype(my_set_comp)>;
class MockClass {
public:
MOCK_METHOD(void, my_func, (my_set));
};
TEST(SetTest, test1) {
MockClass obj{};
my_set a_set{my_set_comp};
a_set.emplace(my_struct{1, 1, 1});
a_set.emplace(my_struct{1, 2, 2});
a_set.emplace(my_struct{1, 3, 3});
EXPECT_CALL(obj, my_func(::testing::Each(::testing::Field(&my_struct::i, 1)))).Times(1);
obj.my_func(a_set);
}
or here.

recursive template function does not compile with Clang?

I have a template function which recurses over a parameter pack. In essence it is meant to map something.Get<A,B,C>() into something.Get<A>().Get<B>().Get<C>().
This can be achieved by doing (full stand-alone source below the fold)
template <typename... Pack> class Struct {
std::tuple<Pack...> mTuple;
template <typename Type> auto &GetRef_internal() {
return std::get<first_true<std::is_same<Type, Pack>::value...>::value>(
mTuple);
}
public:
template <typename Current> Current &GetRef() {
return GetRef_internal<Current>();
}
template <typename Current, typename... Next,
typename std::enable_if<sizeof...(Next) != 0>::type * = nullptr>
auto &GetRef() {
auto current = GetRef_internal<Current>();
return current.GetRef<Next...>();
}
};
where first_true returns the index of the first element which is true.
This compiles with g++, and seemingly on MSVC too using an online compiler. When compiling with clang++ I get the following error though:
test.cxx:40:31: error: expected '(' for function-style cast or type construction
return current.GetRef<Next...>();
~~~~^
test.cxx:38:9: error: cannot deduce return type 'auto &' for function with no return statements
auto &GetRef() {
^
test.cxx:48:12: note: in instantiation of function template specialization 'Struct<Struct<int, Struct<float, float> >, Struct<char>, int>::GetRef<Struct<int, Struct<float, float> >, Struct<float, float> , nullptr>' requested here
.GetRef<Struct<int, Struct<float, float>>, Struct<float, float>>();
^
2 errors generated.
What could cause this?
p.s. The actual 'production code' is more useful than the example makes it seem, but that would be too much to post here.
=========================================================================
#include <tuple>
#include <type_traits>
// Template to check if condition holds true for all members of a parameter
// pack.
template <bool... b> struct BoolArray {};
template <bool... b>
using all_true = std::is_same<BoolArray<b...>, BoolArray<(b, true)...>>;
//helper type trait
template <bool... b> struct first_true {
template <
unsigned index = 0,
typename std::enable_if<index<sizeof...(b)-1>::type * =
nullptr> static constexpr unsigned check() {
return std::get<index>(std::make_tuple(b...)) ? index : check<index + 1>();
}
template <unsigned index = 0,
typename std::enable_if<index >= sizeof...(b)-1>::type * = nullptr>
static constexpr unsigned check() {
return std::get<index>(std::make_tuple(b...)) ? index : 0;
}
static constexpr unsigned value = first_true<b...>::check();
};
//The actual problem struct
template <typename... Pack> class Struct {
std::tuple<Pack...> mTuple;
template <typename Type> auto &GetRef_internal() {
return std::get<first_true<std::is_same<Type, Pack>::value...>::value>(
mTuple);
}
public:
template <typename Current> Current &GetRef() {
return GetRef_internal<Current>();
}
template <typename Current, typename... Next,
typename std::enable_if<sizeof...(Next) != 0>::type * = nullptr>
auto &GetRef() {
auto current = GetRef_internal<Current>();
return current.GetRef<Next...>();
}
};
int main() {
// Define a random nested struct
Struct<Struct<int, Struct<float, float>>, Struct<char>, int> myStruct;
// Then retrieve one of the substructures to instantiate the template
auto substruct =
myStruct
.GetRef<Struct<int, Struct<float, float>>, Struct<float, float>>();
return 0;
}
current.GetRef<Next...> is a dependent name, so you need to specify that GetRef names a template using the template keyword:
return current.template GetRef<Next...>();
See Where and why do I have to put the "template" and "typename" keywords? for more information about dependent names.

Is there a way to generate 2D stretched mesh using CGAL?

I currently use CGAL to generate 2D Delaunay triangulation.One of the mesh control parameter is the maximum length of the triangle edge. The examples suggests that this parameter is a constant. I would like to know how this parameter be made function of some thing else, for example spatial location.
I think Delaunay meshing with variable density is not directly supported by CGAL although you could mesh your regions independently. Alternatively you may have a look at: http://www.geom.at/advanced-mesh-generation/ where I have implemented that as a callback function.
It doesn't look like CGAL provides an example of this but they machinery is all there. The details get a little complicated since the objects that control if triangles need to be refined also have to understand the priority under which triangles get refined.
To do this, I copied Delaunay_mesh_size_criteria_2 to create a new class (Delaunay_mesh_user_criteria_2) that has a spatially varying sizing field. Buried in the class is a function (user_sizing_field) that can be implemented with a varying size field based on location. The code below compares the size of the longest edge of the triangle to the minimum of the sizing field at the three vertices, but you could use a size at the barycenter or circumcenter or even send the entire triangle to the sizing function if you have a good way to compute the smallest allowable size on the triangle altogether.
This is a starting point, although a better solution would,
refactor some things to avoid so much duplication with with existing Delaunay_mesh_size_criteria,
allow the user to pass in the sizing function as an argument to the criteria object, and
be shipped with CGAL.
template <class CDT>
class Delaunay_mesh_user_criteria_2 :
public virtual Delaunay_mesh_criteria_2<CDT>
{
protected:
typedef typename CDT::Geom_traits Geom_traits;
double sizebound;
public:
typedef Delaunay_mesh_criteria_2<CDT> Base;
Delaunay_mesh_user_criteria_2(const double aspect_bound = 0.125,
const Geom_traits& traits = Geom_traits())
: Base(aspect_bound, traits){}
// first: squared_minimum_sine
// second: size
struct Quality : public std::pair<double, double>
{
typedef std::pair<double, double> Base;
Quality() : Base() {};
Quality(double _sine, double _size) : Base(_sine, _size) {}
const double& size() const { return second; }
const double& sine() const { return first; }
// q1<q2 means q1 is prioritised over q2
// ( q1 == *this, q2 == q )
bool operator<(const Quality& q) const
{
if( size() > 1 )
if( q.size() > 1 )
return ( size() > q.size() );
else
return true; // *this is big but not q
else
if( q.size() > 1 )
return false; // q is big but not *this
return( sine() < q.sine() );
}
std::ostream& operator<<(std::ostream& out) const
{
return out << "(size=" << size()
<< ", sine=" << sine() << ")";
}
};
class Is_bad: public Base::Is_bad
{
public:
typedef typename Base::Is_bad::Point_2 Point_2;
Is_bad(const double aspect_bound,
const Geom_traits& traits)
: Base::Is_bad(aspect_bound, traits) {}
Mesh_2::Face_badness operator()(const Quality q) const
{
if( q.size() > 1 )
return Mesh_2::IMPERATIVELY_BAD;
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
double user_sizing_function(const Point_2 p) const
{
// IMPLEMENT YOUR CUSTOM SIZING FUNCTION HERE.
// BUT MAKE SURE THIS RETURNS SOMETHING LARGER
// THAN ZERO TO ALLOW THE ALGORITHM TO TERMINATE
return std::abs(p.x()) + .025;
}
Mesh_2::Face_badness operator()(const typename CDT::Face_handle& fh,
Quality& q) const
{
typedef typename CDT::Geom_traits Geom_traits;
typedef typename Geom_traits::Compute_area_2 Compute_area_2;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance_2;
Geom_traits traits; /** #warning traits with data!! */
Compute_squared_distance_2 squared_distance =
traits.compute_squared_distance_2_object();
const Point_2& pa = fh->vertex(0)->point();
const Point_2& pb = fh->vertex(1)->point();
const Point_2& pc = fh->vertex(2)->point();
double size_bound = std::min(std::min(user_sizing_function(pa),
user_sizing_function(pb)),
user_sizing_function(pc));
double
a = CGAL::to_double(squared_distance(pb, pc)),
b = CGAL::to_double(squared_distance(pc, pa)),
c = CGAL::to_double(squared_distance(pa, pb));
double max_sq_length; // squared max edge length
double second_max_sq_length;
if(a<b)
{
if(b<c) {
max_sq_length = c;
second_max_sq_length = b;
}
else { // c<=b
max_sq_length = b;
second_max_sq_length = ( a < c ? c : a );
}
}
else // b<=a
{
if(a<c) {
max_sq_length = c;
second_max_sq_length = a;
}
else { // c<=a
max_sq_length = a;
second_max_sq_length = ( b < c ? c : b );
}
}
q.second = 0;
q.second = max_sq_length / (size_bound*size_bound);
// normalized by size bound to deal
// with size field
if( q.size() > 1 )
{
q.first = 1; // (do not compute sine)
return Mesh_2::IMPERATIVELY_BAD;
}
Compute_area_2 area_2 = traits.compute_area_2_object();
double area = 2*CGAL::to_double(area_2(pa, pb, pc));
q.first = (area * area) / (max_sq_length * second_max_sq_length); // (sine)
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
};
Is_bad is_bad_object() const
{ return Is_bad(this->bound(), this->traits /* from the bad class */); }
};
I am also interested for variable mesh criteria on the domaine with CGAL. I have found an alternative many years ago : https://www.cs.cmu.edu/~quake/triangle.html
But i am still interested to do the same things with CGAL ... I don't know if it is possible ...

Cannot return a cli array of a generic type

I got this function
array<ItemType>^ GetNextItems(int n) {
auto ret = gcnew Collections::Generic::List < ItemType > ;
for (int i = 0; i < n; i++) {
auto item = GetNextItem();
if (item == ItemType()) break;
ret->Add(item);
}
return ret->ToArray();
}
But the compile gives me an error: cannot convert from 'cli::array< ItemType,1 > ^' to 'cli::array< ItemType,1 > ^'
ItemType is a template parameter ie.
generic <typename ItemType>
I've been staring at this for a while, I can't detect the fault. Why won't it compile?
If ItemType is a .NET/CLR type, then you'll need the ^-hat inside the return type declaration. The ^ is still not included in the actual type declaration.
So it would be something like this:
generic <typename ItemType>
ref class Test
{
array<ItemType ^>^
GetNextItems(int n)
{
List<ItemType ^> ^ ret = gcnew List<ItemType ^>(n);
...
return ret->ToArray();
}
};
Notice the added caret inside the <ItemType ^> return type declaration, but not in the class' generic definition.

How do i get the codec's List of ffmpeg by names?

I have this function in C
int Encoder_GetCurrentCodecType()
{
if (current_codec != NULL)
return (int) current_codec->type;
return AVMEDIA_TYPE_UNKNOWN;
}
But the function return the code of each codec type.
Like: 0,1,2,3,4,5,6,7
If i'm doing for the test in the function i type: AVMediaType::
Then i see the List of all 7 codec's types there is for example:
AVMEDIA_TYPE_AUDIO
So i want to make a function like the one with the int but string or const char* that will return me the names of the types and not the codes.
How can i do it ?
EDIT
In the C file i did:
const char* Encoder_av_get_media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
case AVMEDIA_TYPE_VIDEO: return "video";
case AVMEDIA_TYPE_AUDIO: return "audio";
case AVMEDIA_TYPE_DATA: return "data";
case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
default: return NULL;
}
}
Then in the header file that connecting between the C and C++ i did:
const char* Encoder_av_get_media_type_string(enum AVMediaType media_type);
Then in the C++ header file i did:
property List<String^> ^GetCodec
{
List<String^>^ get()
{
List<String^> ^l = gcnew List<String^>;
String ^s;
s = gcnew String(Encoder_av_get_media_type_string(avm));
l->Add(s);
return l;
}
}
Then in CSHARP i did:
for (int i = 0; i < f.GetCodec.Count; i++)
{
ss.Add(f.GetCodec[i]);
}
So maybe in C++ it shouldn't be property i thought to do something that in CSHARP when i make f.GetCodec. then it will show me a List of all the codec's types names.
Like a property like when i'm doing f.GetCodec.Add and see list of properties so f.GetCodec.(and here i will the list of all types names)
If it's impossible then just to make in CSHARP a List with all types names.
But for now i'm getting only 1 name "video" that's it.
According to this, there exists a function to do just that.
const char* av_get_media_type_string(enum AVMediaType media_type)