How to implement array :: max_size ()?

I create my own template of the class array<T, n> for fun and education. The standard C ++ 0x draft defines the max_size() member function for all containers as distance(begin(), end()) "for the maximum possible container." How to implement this member function for arrays? Am I just returning std::numeric_limits<std::size_t>::max() , or does the result depend on the type of element?


Hmm, both std::array from current g ++ and boost::array return n from max_size() :

 #include <array> #include <boost/array.hpp> #include <iostream> int main() { std::array<int, 11> foo; std::cout << foo.max_size() << std::endl; // prints 11 boost::array<int, 11> bar; std::cout << bar.max_size() << std::endl; // prints 11 } 
+4
source share
5 answers

I agree that the project is somewhat absent.

It is unclear whether container :

  • any container
  • any container of this family
  • any container of this instance of this family

Unlike @Jerry, I would lean to the last option.

Looking at basic_string::append , the description says:

length_error : length_error if size() + n > max_size()

With this remark, I think that the Standard puts its foot in the door for specifying general algorithms, the behavior of which will differ depending on whether the container may or may not work, they can be expanded or not, which can be with max_size .

Thus, container should logically return its maximum length.

Therefore, std::size_t std::array<T,n>::max_size() const { return n; } std::size_t std::array<T,n>::max_size() const { return n; } is a logical choice.

Note that the same max_size definition is logically applicable to fixed-size allocators (and, in particular, to stack-based allocators written by Howard Hinnant).

+4
source

If your array has a fixed size, just return the size ( n in your example), as this is also the maximum size.

+6
source

It must be n , because the array implies a fixed size. And here is a fixed size n .

If this is something other than n , then what does n mean in array<T, n> ?

+4
source

Yes, I think that it usually should depend on the size of the element, so you usually have something like: std::numeric_limits<std::size_t>::max()/sizeof(T) . Otherwise, you give a size that will usually be significantly larger than possible.

Edit: Based on table 93, I must disagree with Nawaz and Jeremiah Wilcock. max_size is clearly described as the size for the largest possible container , and not the largest size to which a specific container can expand.

+3
source

The documentation for max_size says that the function should return "the maximum theoretically possible value of n for which the call allocates (n, 0) can succeed", where n is the number of objects.

STL containers (for example, std :: vector, std :: map, or std :: list) use max_size to calculate the size of the container based on the number of objects, not the number of bytes. Therefore, max_size () should not return the number of bytes available on the operating system, but use the number of bytes available to calculate the number of objects that the allocator can hold.

If you wrote a dispenser class for STL containers, you can implement a max_size () function like this to provide an accurate number of objects instead of being reevaluated with std::numeric_limits<size_type>::max() .

 size_type max_size() const { const unsigned long long bytesAvailable = GetTotalAvailableMemory(); const unsigned long long maxPossibleObjects = bytesAvailable / sizeof(value_type); return maxPossibleObjects; } 

You can implement GetTotalAvailableMemory () as these functions, depending on your operating system. Any of them will return the number of unallocated bytes that the software process can use.

 #if defined(unix) || defined(__unix__) || defined(__unix) #include <unistd.h> unsigned long long GetTotalAvailableMemory() { const long pageCount = sysconf( _SC_PHYS_PAGES ); const long pageSize = sysconf( _SC_PAGE_SIZE ); const unsigned long long totalBytes = pageCount * pageSize; return totalBytes; } #endif #if defined(_WIN64) || defined(_WIN64) #include <windows.h> unsigned long long GetTotalAvailableMemory() { MEMORYSTATUSEX status; status.dwLength = sizeof( status ); GlobalMemoryStatusEx( &status ); return status.ullAvailVirtual; } #endif 
0
source

Source: https://habr.com/ru/post/1340646/


All Articles