Opened 10 years ago

Last modified 10 years ago

#7063 new Feature Requests

try_unhex() that doesn't throw on bad input

Reported by: Olaf van der Spek <olafvdspek@…> Owned by: Marshall Clow
Milestone: To Be Determined Component: algorithm
Version: Boost 1.51.0 Severity: Problem
Keywords: Cc:

Description

Could you provide an unhex() variant that doesn't throw on bad input, but returns an error (non-false) instead?

Change History (8)

comment:1 by Marshall Clow, 10 years ago

unhex already returns a value; the output iterator (so that you can chain operations).

comment:2 by Olaf van der Spek <olafvdspek@…>, 10 years ago

I know. This request is for something like bool try_unhex(const T& in, U& out) Having to wrap unhex() into a try/catch block is quite cumbersome and sometime exceptions can't be used at all.

comment:3 by Marshall Clow, 10 years ago

Something like this?

Of course, it will still throw if a memory allocation fails. Or the output iterator throws. Or the input iterator throws. Or one of the assignments throw.

   template <typename InputIter, typename OutputIter>
   bool try_unhex ( InputIter first, InputIter last, OutputIter out ) {
      try {
         (void) unhex ( first, last, out );
         return true;
         }
      catch ( const hex_decode_error & ) {}
      return false;
      }

Note:

  • if you pass the output iterator by value, then you lose any changes that are made.
  • If you pass the output iterator by reference, then you can't use an unnamed temporary (such as the result of std::back_inserter)

In any case, I'm not convinced that this is a good idea.

comment:4 by Olaf van der Spek <olafvdspek@…>, 10 years ago

No, I was thinking of range-based input and container-based output. Like this:

std::string a = unhex("ABCD"); // may throw on bad input
std::string b;
if (!unhex("ABCD", b)
  return ERROR;

comment:5 by Marshall Clow, 10 years ago

Olaf --

Thinking some more about this, I don't think this belongs in boost, but rather in your application code.

It throws away useful information, a big no-no in generic code. (The cause of the failure, and the point of failure)

Of course, in your specific use case, throwing away this information (or reducing all failures to a single bit) may be perfectly fine, and that's why it should live in your code.

comment:6 by Olaf van der Spek <olafvdspek@…>, 10 years ago

The point of failure (in the input stream) isn't available anyway, is it?

comment:7 by Marshall Clow, 10 years ago

Not directly:

  • In the case of "not enough input" the point of failure is the end of the input.
  • In the case of "non-hex input", the character that caused the error is attached to the exception that is thrown

So you can figure out where the error occurred.

comment:8 by Olaf van der Spek <olafvdspek@…>, 10 years ago

Nice!

It throws away useful information, a big no-no in generic code.

Since it's a new variant, the old variant is still available if that info is required, isn't it?

Note: See TracTickets for help on using tickets.