[util] Any interest in address_of_first_nonarray_elem ?
Working with built-in array objects I find myself repeatedly needing to get the address of the first non-array element. This is so I can do generic array comparisons and copies without resorting to multiple loops. For example: template <typename T, std::size_t N> bool generic_array_equal(T (&lhs)[N], T const (&rhs)[N]) { return std::equal( address_of_first_nonarray_elem(lhs), address_of_first_nonarray_elem(lhs) + total_extent<T[N]>::size, address_of_first_nonarray_elem(rhs)); } Any interest in adding such a function to the util library? Mostafa
Mostafa <mostafa_working_away <at> yahoo.com> writes:
Working with built-in array objects I find myself repeatedly needing to get the address of the first non-array element. This is so I can do generic array comparisons and copies without resorting to multiple loops. For example:
template <typename T, std::size_t N> bool generic_array_equal(T (&lhs)[N], T const (&rhs)[N]) { return std::equal( address_of_first_nonarray_elem(lhs), address_of_first_nonarray_elem(lhs) + total_extent<T[N]>::size, address_of_first_nonarray_elem(rhs)); }
Any interest in adding such a function to the util library?
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)? Joaquín M López Muñoz Telefónica Digital
On Sun, 01 Dec 2013 23:56:41 -0800, Joaquin M Lopez Munoz <joaquin@tid.es> wrote:
Mostafa <mostafa_working_away <at> yahoo.com> writes:
Working with built-in array objects I find myself repeatedly needing to get the address of the first non-array element. This is so I can do generic array comparisons and copies without resorting to multiple loops. For example:
template <typename T, std::size_t N> bool generic_array_equal(T (&lhs)[N], T const (&rhs)[N]) { return std::equal( address_of_first_nonarray_elem(lhs), address_of_first_nonarray_elem(lhs) + total_extent<T[N]>::size, address_of_first_nonarray_elem(rhs)); }
Any interest in adding such a function to the util library?
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)?
No. The motivating use case for this were built-in multidimensional arrays. I wanted a generic way to compare and copy them without resorting to nested loops. For example: typedef int ArrType[2][3]; ArrType a1 = { {0, 1, 2}, {3, 4, 5} }; ArrType a2 = { {0, 1, 2}, {3, 4, 5} }; // Prints 0. std::cout << "Std Equal: " << std::equal(a1, a1 + 2, a2) << "\n"; // Prints 1. Obviously address_of_first_nonarray_elem would be used instead of subscripting. std::cout << "Flattened Std Equal: " << std::equal(a1[0], a1[0] + 6, a2[0]) << "\n"; In the above example the address of the first array element won't do, since that itself is an array. In general what is needed is the address of the first non-array element, and in the above case that would be &a1[0][0] or a1[0].
Mostafa <mostafa_working_away <at> yahoo.com> writes:
On Sun, 01 Dec 2013 23:56:41 -0800, Joaquin M Lopez Munoz <joaquin <at>
tid.es>
wrote:
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)?
No. The motivating use case for this were built-in multidimensional arrays. I wanted a generic way to compare and copy them without resorting to nested loops.
For example:
typedef int ArrType[2][3];
ArrType a1 = { {0, 1, 2}, {3, 4, 5} }; ArrType a2 = { {0, 1, 2}, {3, 4, 5} };
// Prints 0. std::cout << "Std Equal: " << std::equal(a1, a1 + 2, a2) << "\n"; // Prints 1. Obviously address_of_first_nonarray_elem would be used instead of subscripting. std::cout << "Flattened Std Equal: " << std::equal(a1[0], a1[0] + 6, a2[0])
Ok, I got it now. The name is not very illuminating, maybe flat_begin/flat_end or a flat_view with begin/end/size would do better. Joaquín M López Muñoz Telefónica Digital
Hi, 1) are you aware of boost::multi_array? http://www.boost.org/doc/libs/1_55_0/libs/multi_array/doc/index.html I don't now this library well but seems that multi_array gives you correct == operator. 2) flat_begin/flat_end name is more intuitive for me. Regards, Piotr On 2 December 2013 11:34, Joaquin M Lopez Munoz <joaquin@tid.es> wrote:
Mostafa <mostafa_working_away <at> yahoo.com> writes:
On Sun, 01 Dec 2013 23:56:41 -0800, Joaquin M Lopez Munoz <joaquin <at>
tid.es>
wrote:
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)?
No. The motivating use case for this were built-in multidimensional arrays. I wanted a generic way to compare and copy them without resorting to nested loops.
For example:
typedef int ArrType[2][3];
ArrType a1 = { {0, 1, 2}, {3, 4, 5} }; ArrType a2 = { {0, 1, 2}, {3, 4, 5} };
// Prints 0. std::cout << "Std Equal: " << std::equal(a1, a1 + 2, a2) << "\n"; // Prints 1. Obviously address_of_first_nonarray_elem would be used instead of subscripting. std::cout << "Flattened Std Equal: " << std::equal(a1[0], a1[0] + 6, a2[0])
Ok, I got it now. The name is not very illuminating, maybe flat_begin/flat_end or a flat_view with begin/end/size would do better.
Joaquín M López Muñoz Telefónica Digital
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Mon, 02 Dec 2013 06:13:26 -0800, Piotr Wygocki <vwygos@gmail.com> wrote:
Hi,
1) are you aware of boost::multi_array?
http://www.boost.org/doc/libs/1_55_0/libs/multi_array/doc/index.html
I don't now this library well but seems that multi_array gives you correct == operator.
Yes. Unfortunately, multi_array_ref doesn't work out of the box "generically". That's because its ctor doesn't take an array reference, rather it takes a data pointer and an extents data structure. So the extents data structure has to be constructed by the user, even though for built-in arrays that have all their extents specified this is determinable at compile time and I think that should be the library's responsibility. In addition I don't know if it's desirable to pull all of multi_array when only a few utilities are needed. Mostafa
2013/12/2 Joaquin M Lopez Munoz <joaquin@tid.es>
Mostafa <mostafa_working_away <at> yahoo.com> writes:
On Sun, 01 Dec 2013 23:56:41 -0800, Joaquin M Lopez Munoz <joaquin <at>
tid.es>
wrote:
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)?
No. The motivating use case for this were built-in multidimensional arrays. I wanted a generic way to compare and copy them without resorting to nested loops.
For example:
typedef int ArrType[2][3];
ArrType a1 = { {0, 1, 2}, {3, 4, 5} }; ArrType a2 = { {0, 1, 2}, {3, 4, 5} };
// Prints 0. std::cout << "Std Equal: " << std::equal(a1, a1 + 2, a2) << "\n"; // Prints 1. Obviously address_of_first_nonarray_elem would be used instead of subscripting. std::cout << "Flattened Std Equal: " << std::equal(a1[0], a1[0] + 6, a2[0])
Ok, I got it now. The name is not very illuminating, maybe flat_begin/flat_end or a flat_view with begin/end/size would do better.
+1 for flat_view Regards, Kris
On Mon, 02 Dec 2013 02:34:15 -0800, Joaquin M Lopez Munoz <joaquin@tid.es> wrote:
Mostafa <mostafa_working_away <at> yahoo.com> writes:
On Sun, 01 Dec 2013 23:56:41 -0800, Joaquin M Lopez Munoz <joaquin <at>
tid.es>
wrote:
Why the "non"? Shouldn't the name be "address_of_first_array_elem"? How is this different from std::begin(lhs)?
No. The motivating use case for this were built-in multidimensional arrays. I wanted a generic way to compare and copy them without resorting to nested loops.
For example:
typedef int ArrType[2][3];
ArrType a1 = { {0, 1, 2}, {3, 4, 5} }; ArrType a2 = { {0, 1, 2}, {3, 4, 5} };
// Prints 0. std::cout << "Std Equal: " << std::equal(a1, a1 + 2, a2) << "\n"; // Prints 1. Obviously address_of_first_nonarray_elem would be used instead of subscripting. std::cout << "Flattened Std Equal: " << std::equal(a1[0], a1[0] + 6, a2[0])
Ok, I got it now. The name is not very illuminating, maybe flat_begin/flat_end or a flat_view with begin/end/size would do better.
Thanks. I think you're on the right track. Why not just a flat_view along the following lines of: template <typename T, std::size_t> typename flat_view_result<T[N]>::type flat_view( T (&arr)[N] ); Where flat_view_result<T[N]>::type is a Random Access Range. I think this maybe a good addition to the range library.
From: mostafa_working_away@yahoo.com Date: Sun, 1 Dec 2013 20:10:53 -0800
Working with built-in array objects I find myself repeatedly needing to get the address of the first non-array element. This is so I can do generic array comparisons and copies without resorting to multiple loops. For example:
template <typename T, std::size_t N> bool generic_array_equal(T (&lhs)[N], T const (&rhs)[N]) { return std::equal( address_of_first_nonarray_elem(lhs), address_of_first_nonarray_elem(lhs) + total_extent<T[N]>::size, address_of_first_nonarray_elem(rhs)); }
Any interest in adding such a function to the util library?
I needed code like this when developing a multiple-dimension extension to "array." What about (not tested; quasi-C++14): //===== template < typename T> constexpr auto inner_addressof( T &&t, false_type ) { return addressof(forward<T>(t)); } template < typename T, size_t N> constexpr auto inner_addressof( T (&t)[N], true_type ) { return inner_addressof(t[0], integral_constant<bool, rank<T>::value>{}); } template < typename T> constexpr auto inner_addressof( T &&t ) { return inner_addressof(forward<T>(t), integral_constant<bool, rank<T>::value>{}); } template < typename T> struct inner_element_count : integral_constant<size_t, sizeof(T) / sizeof(remove_all_extents_t<T>)> { }; //===== No need for a custom range class. Daryle W.
participants (5)
-
Daryle Walker
-
Joaquin M Lopez Munoz
-
Krzysztof Czainski
-
Mostafa
-
Piotr Wygocki