Opened 11 years ago
Last modified 11 years ago
#6160 assigned Feature Requests
support for (istream >> array < char >)
Reported by: | Owned by: | Marshall Clow | |
---|---|---|---|
Milestone: | To Be Determined | Component: | array |
Version: | Boost 1.44.0 | Severity: | Cosmetic |
Keywords: | Cc: |
Description
array < T >
is a replacement forT []
- the standard library provides the syntax
(istream >> char [])
and(ostream << char const [])
- Currently,
(istream >> array < char >)
does not mean anything - this functionality cannot be simulated even with
std:: copy_n < istreambuf_iterator >
without manual termination and much verbosity
My implementation
#include <boost/array.hpp> /* for ::boost:: array */ #include <boost/version.hpp> #if +BOOST_VERSION <= 0313720 #include <iomanip> /* for ::std:: setw */ namespace boost { /* helper classes to prevent ambiguity in matching array < char > */ namespace detail_ { /* normally, other char for every character type is char */ template < class P_C > class other_char { public: typedef char type; }; /* but other_char is undefined for char */ template <> class other_char < char > {}; /* class same_stream fails for istream */ template < class P_S, class P_C = typename other_char < typename P_S:: char_type >:: type > class same_stream { public: typedef P_S stream; }; } /* template input */ template < class P_C, class P_T, ::std:: size_t P_N > static inline ::std:: basic_istream < P_C, P_T > &operator >> (::std:: basic_istream < P_C, P_T > &p_s, ::boost:: array < P_C, P_N > &p_a) { return p_s >> ::std:: setw (p_a. static_size) >> p_a. data (); } /* character input, disabled for type char to avoid ambiguity */ template < class P_C, class P_T, ::std:: size_t P_N > static inline typename detail_:: same_stream < ::std:: basic_istream < P_C, P_T > >:: stream &operator >> (::std:: basic_istream < P_C, P_T > &p_s, ::boost:: array < char, P_N > &p_a) { return p_s >> ::std:: setw (p_a. static_size) >> p_a. data (); } /* template output */ template < class P_C, class P_T, ::std:: size_t P_N > static inline ::std:: basic_ostream < P_C, P_T > &operator << (::std:: basic_ostream < P_C, P_T > &p_s, ::boost:: array < P_C, P_N > const &p_a) { return p_s << p_a. begin (); } /* character output, disabled for type char */ template < class P_C, class P_T, ::std:: size_t P_N > static inline typename detail_:: same_stream < ::std:: basic_ostream < P_C, P_T > >:: stream &operator << (::std:: basic_ostream < P_C, P_T > &p_s, ::boost:: array < char, P_N > const &p_a) { return p_s << p_a. begin (); }} #endif /* BOOST_VERSION */ #include <cstdlib> /* for EXIT_SUCCESS */ #include <cstdio> /* for BUFSIZ */ #include <iostream> /* for ::std:: cin */ int main () { // char (&x) [+BOOST_VERSION] = 0; #ifdef ARRAY_IN_NATIVE /* native code */ char t [+BUFSIZ]; return ::std:: cin >> ::std:: setw (+BUFSIZ) >> t && ::std:: cout << t << '\n'? +EXIT_SUCCESS: +EXIT_FAILURE; #else /* ARRAY_IN_NATIVE */ /* equivalent Boost code */ ::boost:: array < char, +BUFSIZ > t; /* check that character input compiles for wchar_t */ (void) sizeof (std:: wcin >> t); return ::std:: cin >> t && ::std:: cout << t << '\n'? +EXIT_SUCCESS: +EXIT_FAILURE; #endif /* ARRAY_IN_NATIVE */ }
Change History (10)
follow-up: 2 comment:1 by , 11 years ago
comment:2 by , 11 years ago
Replying to cornedbee:
the standard library provides the syntax (istream >> char []) and (ostream << char const [])
No, it provides istream >> char* and ostream << char const*. As such, you can quite easily use the c_array() and data() members to get pointers to the data: istream >> ar.c_array() and ostream << ar.data().
The call invites buffer overflow and undefined behaviour. If it were that simple, I would not bother writing so many words here.
istream >> ar.c_array ()
follow-up: 5 comment:3 by , 11 years ago
Status: | new → assigned |
---|
I don't see the difference between:
istream >> char *
, istream >> char []
and istream >> boost::array<char>
in terms of buffer overflow prevention.
It seems to me that in each case, it is the responsibility of the person providing the input to make sure that the input fits into the provided buffer.
Am I missing something here?
follow-up: 6 comment:4 by , 11 years ago
char []
has unknown length, array < char >
has known length, therefore >> array
is safer than >> char []
, and my code, attached, q.v., uses this information to prevent buffer overflow.
comment:5 by , 11 years ago
Replying to marshall:
It seems to me that in each case, it is the responsibility of the person providing the input to make sure that the input fits into the provided buffer.
This is not possible for general streams, unless your machine happens to be clairvoyant.
follow-up: 7 comment:6 by , 11 years ago
Replying to ne01026@…:
char []
has unknown length,array < char >
has known length, therefore>> array
is safer than>> char []
, and my code, attached, q.v., uses this information to prevent buffer overflow.
char []
has known length - sizeof is your friend here.
I see where your code is using the length to prevent a buffer overflow - but doing that at every stream extraction is error-prone, at best. It seems to me that (famous last words) that if this were to be implemented, it should never overflow the bounds of the array.
Do you know if this was considered for std::array?
follow-up: 8 comment:7 by , 11 years ago
Replying to marshall:
Replying to ne01026@…:
char []
has unknown length,array < char >
has known length, therefore>> array
is safer than>> char []
, and my code, attached, q.v., uses this information to prevent buffer overflow.
char []
has known length - sizeof is your friend here.
sizeof (char [])
is undefined.
I see where your code is using the length to prevent a buffer overflow - but doing that at every stream extraction is error-prone, at best. It seems to me that (famous last words) that if this were to be implemented, it should never overflow the bounds of the array.
The extraction operator will not extract more characters than the array length, minus one, so where is the error?
Do you know if this was considered for std::array?
I do not know; however, given that std takes from boost and not the other way round, I decided to put it here first. At least, the thing seems obvious and straighforward to me. The standard library has special semantics for (native) character arrays, and so should we.
I tried to discuss the matter at #boost and I was told to file an enhancement, so here it is.
follow-up: 9 comment:8 by , 11 years ago
Replying to ne01026@…:
Replying to marshall:
Replying to ne01026@…:
char []
has unknown length,array < char >
has known length, therefore>> array
is safer than>> char []
, and my code, attached, q.v., uses this information to prevent buffer overflow.
char []
has known length - sizeof is your friend here.
sizeof (char [])
is undefined.
Sorry - I was imprecise: char [N] has size N for all N > 0
Do you know if this was considered for std::array?
I do not know; however, given that std takes from boost and not the other way round, I decided to put it here first. At least, the thing seems obvious and straighforward to me. The standard library has special semantics for (native) character arrays, and so should we.
I tried to discuss the matter at #boost and I was told to file an enhancement, so here it is.
And I'm glad that you did - and now we are discussing it.
BTW - if this were to become part of boost, it would be more complicated. You should be able to extract from std::wcin to a boost::array<wchar_t>, for example.
follow-up: 10 comment:9 by , 11 years ago
Replying to marshall:
Replying to ne01026@…:
Replying to marshall:
Replying to ne01026@…:
char []
has unknown length,array < char >
has known length, therefore>> array
is safer than>> char []
, and my code, attached, q.v., uses this information to prevent buffer overflow.
char []
has known length - sizeof is your friend here.
sizeof (char [])
is undefined.Sorry - I was imprecise: char [N] has size N for all N > 0
Unfortunately, the standard library does not provide istream >> char (&) [N]
as some older compilers are unable to match against such a template, so the best we can do is to define this thing for array.
BTW - if this were to become part of boost, it would be more complicated. You should be able to extract from std::wcin to a boost::array<wchar_t>, for example.
I already do, that is why the code is so ugly :-(
comment:10 by , 11 years ago
BTW - if this were to become part of boost, it would be more complicated. You should be able to extract from std::wcin to a boost::array<wchar_t>, for example.
I already do, that is why the code is so ugly :-(
I apologize. I clearly did not read your code closely enough.
No, it provides istream >> char* and ostream << char const*. As such, you can quite easily use the c_array() and data() members to get pointers to the data: istream >> ar.c_array() and ostream << ar.data().