when copying arrays using std::copy is there a way to check to see if the copy went through correctly? especially if you have like hex values in an unsigned char array. I am not sure how one can verify that the copy went through and even if it did the values that were in one array copied over correctly.
Virtually the only way for a copy to fail is if you're copying to something like a back_insert_iterator, in which case there's a possibility of allocation in the destination container failing. This will normally1 be reported by an exception being thrown.
1For those who want the gory details, in this case "normally" means you haven't provided your own allocator that does something other than throwing an exception in case of failure.
Edit: Perhaps I should have been more explicit: I was talking about a failure that you'd stand a chance of detecting. The precondition on std::copy says that the destination iterator must not be in the source range. Violating that leads to undefined behavior. Likewise, if you do an assignment (either directly or via an algorithm like copy or transform) that's out of range of the target type, you (again) get undefined behavior.
The definition of undefined behavior is that the standard places no requirements on the implementation. In other words, if you do this, anything can happen. Nothing about the behavior of the program is guaranteed at all. There's no sensible way to talk about how to detect such a thing having happened, because the language says that if your program does such a thing, you can't depend on anything.
Edit again: Since there seems to be some misunderstanding about undefined behavior. To do any good, if you're concerned with things that might lead to undefined behavior, you need to prevent them from happening, rather than attempting to do the copy and then try to figure out whether it succeeded. By then it's too late; if the program does something that's undefined, all the behavior of the program is undefined.
So, to deal with the possibility of the destination iterator being within the range of the source iterators, or that the source data is outside the range of the destination data type, you need to check for those up-front, and never even attempt the undefined behavior.
template <class T, class U>
safe_copy(T source_start, T source_end, U dest) {
if (std::less(source_start, dest) && std::less(dest, source_end))
throw(std::range_error("Output iterator within input range");
std::transform(source_start, source_end, dest, checked_convert);
}
For the moment, I haven't tried to define checked_convert. It might do a saturating conversion, or throw an exception if a value is out of range, etc., -- depending entirely on the type of data involved. One way or another, however, it assures that the source value fits in the destination range before assignment to the destination is attempted.
You can double-check that the copy succeeded by using this: (assert comes from <cassert>)
assert ( std::equal( src_first, src_last, dst ) );
This will catch problems resulting from src_first < dst < src_last. A better way, though, would be to assert that condition directly: (this requires random-access iterators, ie from a vector or deque, and they must belong to the same container — which is usually the case if you're concerned with overlap)
assert ( src_last < dst || dst <= src_first );
But you seem concerned with other kinds of problem, such as type compatibility. There is no silver bullet for that, but the first suggestion above will keep you safe as long as the source and destination types can be tested for equality.
An aside: hex is just the base-16 number system, so any data is "hex values" if written in base-16.
Edit: I got a couple downvotes because assert isn't appropriate for production code, and because typecasts are supposedly unsafe because some cases are not defined by the C++ standard.
First, if you don't want to assert, then remove the assert and use the condition for something else! Not rocket science.
Second, it's your responsibility to ensure that you don't crash with a numeric exception. First off, there are no exceptions and no undefined behavior in integer casts. So the above use of std::equal is guaranteed to work for any native integral types and values, period. Also not rocket science.
If you are using floating-point types, then C++ allows the possibility of a crash and burn when if you cast a float to an int, using std::copy or otherwise: it leaves the behavior of a float-to-int overflow undefined. Does this mean you can't ever cast a float to an int without first checking that overflow won't occur? Of course not! C++ does not define the behavior, but IEEE 754 does. Moreover, IEEE 754 defines all the behavior of all the operations you can perform (undefined values notwithstanding), and it has been ubiquitous for well over 20 years.
IEEE 754 further recommends that the default operating environment never raise any numeric exceptions, and POSIX guarantees this. That means that you can do anything to any floating-point numbers and not worry about crashing! (As long as you are in a POSIX or similar numeric system and you haven't specifically enabled exceptions.)
Crashing and "undefined behavior" out of the way, testing for equality afterwards is numerically a solid operation. C++ compares native-type numbers by casting (promoting) the operand of "lesser" type to one of "greater" type, per §5 ¶7 of the standard. Equality will only hold if both values can be represented in the type of greater range, and they are the same number in that type.
Values which are not numbers may fail. If you copy a vector with a NaN in it, the std::equal call will return false because NaN cannot equal anything else, not even an identical NaN, because NaN stands for Not a Number and equality isn't something it does.
Hence my disclaimer "not a silver bullet… safe as long as the source and destination types can be tested for equality." You need to generally be aware of what you're doing. Pushing the bounds of floating-point tends to cause headaches. Do your homework.
But crashing will not happen, undefined behavior will not incur that, despite the standard's disclaimer about undefined behavior, because the behavior IS defined somewhere else, either in IEEE 754 or (unlikely) in your FPU manual if it is not compliant.
Edit 2: the checked_convert function mentioned in the other answer is just dancing around a well known utility, boost::numeric_cast. If you want to safely cast numbers and get specific information about how the operation failed, if it did, that is the tool you want. Don't attempt to write your own code, it's tricky.