BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_error.h
Go to the documentation of this file.
1/// @file bslstl_error.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_error.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_ERROR
9#define INCLUDED_BSLSTL_ERROR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14// BDE_VERIFY pragma: -TP25 // CLASSES are not defined in C++11
15
16/// @defgroup bslstl_error bslstl_error
17/// @brief Provide standard compliant versions of <system_error> classes.
18/// @addtogroup bsl
19/// @{
20/// @addtogroup bslstl
21/// @{
22/// @addtogroup bslstl_error
23/// @{
24///
25/// <h1> Outline </h1>
26/// * <a href="#bslstl_error-purpose"> Purpose</a>
27/// * <a href="#bslstl_error-classes"> Classes </a>
28/// * <a href="#bslstl_error-description"> Description </a>
29/// * <a href="#bslstl_error-usage"> Usage </a>
30/// * <a href="#bslstl_error-example-1-tbd"> Example 1: TBD </a>
31///
32/// # Purpose {#bslstl_error-purpose}
33/// Provide standard compliant versions of <system_error> classes.
34///
35/// # Classes {#bslstl_error-classes}
36///
37/// - bsl::error_category: a standard compliant version of @ref error_category
38/// - bsl::error_code: a standard complaint version of @ref error_code
39/// - bsl::error_condition: a standard complaint version of @ref error_condition
40///
41/// **Canonical header:** bsl_system_error.h
42///
43/// # Description {#bslstl_error-description}
44/// This component defines classes `bsl::error_category`,
45/// `bsl::error_code`, and `bsl::error_condition`, global functions
46/// `bsl::generic_category`, `bsl::system_category`, `bsl::make_error_code`, and
47/// `bsl::make_error_condition`, and a variety of operators that provide
48/// implementations of the C++11 @ref system_error facility. In C++11 mode, the
49/// vendor-supplied `<system_error>` implementation is used instead, and the
50/// corresponding names from `std` are imported into `bsl`.
51///
52/// ## Usage {#bslstl_error-usage}
53///
54///
55/// In this section we show intended use of this component.
56///
57/// ### Example 1: TBD {#bslstl_error-example-1-tbd}
58///
59///
60/// We are in the process of determining best practices for using error codes in
61/// our programming environment.
62/// @}
63/** @} */
64/** @} */
65
66/** @addtogroup bsl
67 * @{
68 */
69/** @addtogroup bslstl
70 * @{
71 */
72/** @addtogroup bslstl_error
73 * @{
74 */
75
76#include <bslscm_version.h>
77#include <bslstl_errc.h>
78#include <bslstl_hash.h>
81
82#include <bslh_hash.h>
83
84#include <bslmf_enableif.h>
86
87#include <bsls_keyword.h>
89#include <bsls_platform.h>
91
92#include <errno.h>
93#include <string.h>
94
95#include <cstring>
96#include <functional>
97#include <iosfwd>
98#include <stdexcept>
99#include <string>
100
101#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
102#include <bsls_nativestd.h>
103#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
104
105#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
106
107#include <system_error>
108
109namespace bsl {
110
111using std::error_category;
112using std::error_code;
113using std::error_condition;
114using std::generic_category;
115using std::system_category;
116using std::make_error_code;
117using std::make_error_condition;
118
119} // close namespace bsl
120
121#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
122
123namespace bsl {
124
125template <>
126struct hash<error_code> : std::hash<error_code>
127{
128};
129
130template <>
131struct hash<error_condition> : std::hash<error_condition>
132{
133};
134
135} // close namespace bsl
136
137#endif
138
139#else
140
141namespace bsl {
142
143// FORWARD DECLARATIONS
144class error_code;
145class error_condition;
146
147 // ====================
148 // class error_category
149 // ====================
150
151/// This `class` acts as a base for types that represent the source and
152/// encoding of error categories.
153///
154/// See @ref bslstl_error
155class error_category {
156
157 private:
158 // PRIVATE CREATORS
159 error_category(const error_category&); // = delete
160
161 // PRIVATE MANIPULATORS
162 error_category& operator=(const error_category&); // = delete
163
164 public:
165 // CREATORS
166
167 /// Create an object of this type.
168 error_category();
169
170 /// Destroy this object.
171 virtual ~error_category();
172
173 // ACCESSORS
174
175 /// Return an @ref error_condition object initialized with the specified
176 /// `value` and this object as the error category.
177 virtual error_condition default_error_condition(int value) const
179
180 /// Return, for the error category defined by this object, whether the
181 /// specified `code` and `condition` are considered equivalent.
182 virtual bool equivalent(int code, const error_condition& condition) const
184 virtual bool equivalent(const error_code& code, int condition) const
186
187 /// Return a string describing the error condition denoted by the
188 /// specified `value`.
189 virtual std::string message(int value) const = 0;
190
191 /// Return the name of this error category.
192 virtual const char *name() const BSLS_KEYWORD_NOEXCEPT = 0;
193
194 /// Return whether this object is the same as the specified `other`.
195 bool operator==(const error_category& other) const BSLS_KEYWORD_NOEXCEPT;
196
197 /// Return whether this object is different than the specified `other`.
198 bool operator!=(const error_category& other) const BSLS_KEYWORD_NOEXCEPT;
199
200 /// Return whether this object precedes the specified `other` in a total
201 /// ordering of @ref error_category objects.
202 bool operator<(const error_category& other) const BSLS_KEYWORD_NOEXCEPT;
203};
204
205 // ================
206 // class error_code
207 // ================
208
209/// This `class` represents a system-specific error value.
210///
211/// See @ref bslstl_error
212class error_code {
213
214 private:
215 // PRIVATE TYPES
216 typedef BloombergLP::bsls::UnspecifiedBool<error_code> UnspecifiedBool;
217 typedef UnspecifiedBool::BoolType BoolType;
218
219 public:
220 // CREATORS
221
222 /// Create an object of this type initialized with value 0 and system
223 /// category.
224 error_code();
225
226 /// Create an object of this type initialized with the specified `value`
227 /// and `category`.
228 error_code(int value, const error_category& category);
229
230 /// Construct an object of this type initialized with the specified
231 /// `value` and its category (found from an overloaded call to
232 /// `make_error_code`). Note that this constructor exists only for
233 /// those types designated as error codes via the `is_error_code_enum`
234 /// trait template.
235 template <class ERROR_CODE_ENUM>
236 error_code(ERROR_CODE_ENUM value,
237 typename enable_if<is_error_code_enum<ERROR_CODE_ENUM>::value,
238 BoolType>::type = 0); // IMPLICIT
239
240 // MANIPULATORS
241
242 /// Set this object to hold the specified `value` and `category`.
243 void assign(int value, const error_category& category);
244
245 /// Set this object to hold the specified `value` and its category
246 /// (found from an overloaded call to `make_error_code`). Note that
247 /// this operator exists only for those types designated as error codes
248 /// via the `is_error_code_enum` trait template. Note that this object
249 /// is set to the generic rather than system category, because that is
250 /// what the standard specifies.
251 template <class ERROR_CODE_ENUM>
252 typename enable_if<is_error_code_enum<ERROR_CODE_ENUM>::value,
253 error_code&>::type
254 operator=(ERROR_CODE_ENUM value);
255
256 /// Set this object to hold the value 0 and the system category.
257 void clear();
258
259 // ACCESSORS
260
261 /// Return a `const` reference to the category held by this object.
262 const error_category& category() const;
263
264 /// Return an @ref error_condition object initialized with the value and
265 /// category of this object.
266 error_condition default_error_condition() const;
267
268 /// Return a string describing this object.
269 std::string message() const;
270
271 /// Return the value held by this object.
272 int value() const;
273
274 /// Return whether the value held by this object is non-zero.
275 operator BoolType() const;
276
277 private:
278 // DATA
279 int d_value; // error code value
280 const error_category *d_category_p; // error category
281};
282
283 // =====================
284 // class error_condition
285 // =====================
286
287/// This `class` represents a portable error value.
288///
289/// See @ref bslstl_error
290class error_condition {
291
292 private:
293 // PRIVATE TYPES
294 typedef BloombergLP::bsls::UnspecifiedBool<error_condition>
295 UnspecifiedBool;
296 typedef UnspecifiedBool::BoolType BoolType;
297
298 public:
299 // CREATORS
300
301 /// Create an object of this type initialized with value 0 and generic
302 /// category.
303 error_condition();
304
305 /// Create an object of this type initialized with the specified `value`
306 /// and `category`.
307 error_condition(int value, const error_category& category);
308
309 /// Construct an object of this type initialized with the specified
310 /// `value` and its category (found from an overloaded call to
311 /// `make_error_condition`). Note that this constructor exists only for
312 /// those types designated as error conditions via the
313 /// `is_error_condition_enum` trait template.
314 template <class ERROR_CONDITION_ENUM>
315 error_condition(ERROR_CONDITION_ENUM value,
316 typename enable_if<
317 is_error_condition_enum<ERROR_CONDITION_ENUM>::value,
318 BoolType>::type = 0); // IMPLICIT
319
320 // MANIPULATORS
321
322 /// Set this object to hold the specified `value` and `category`.
323 void assign(int value, const error_category& category);
324
325 /// Set this object to hold the specified `value` and its category
326 /// (found from an overloaded call to `make_error_condition`). Note
327 /// that this operator exists only for those types designated as error
328 /// conditions via the `is_error_condition_enum` trait template.
329 template <class ERROR_CONDITION_ENUM>
330 typename enable_if<is_error_condition_enum<ERROR_CONDITION_ENUM>::value,
331 error_condition&>::type
332 operator=(ERROR_CONDITION_ENUM value);
333
334 /// Set this object to hold the value 0 and the generic category.
335 void clear();
336
337 // ACCESSORS
338
339 /// Return a `const` reference to the category held by this object.
340 const error_category& category() const;
341
342 /// Return a string describing this object.
343 std::string message() const;
344
345 /// Return the value held by this object.
346 int value() const;
347
348 /// Return whether the value held by this object is non-zero.
349 operator BoolType() const;
350
351 private:
352 // DATA
353 int d_value; // error code value
354 const error_category *d_category_p; // error category
355};
356
357// FREE FUNCTIONS
358
359/// Return a `const` reference to the unique generic category object.
360const error_category& generic_category();
361
362/// Return a `const` reference to the unique system category object.
363const error_category& system_category();
364
365/// Return an @ref error_code object holding the specified `value` and generic
366/// category. Note that the category is generic rather than system because
367/// that is what the standard specifies.
368error_code make_error_code(errc::Enum value);
369
370/// Return an @ref error_condition object holding the specified `value` and
371/// generic category.
372error_condition make_error_condition(errc::Enum value);
373
374/// Hash the specified `object` using the specified `hashAlgorithm`.
375template <class HASHALG>
376void hashAppend(HASHALG& hashAlgorithm, const error_code& object);
377
378/// Hash the specified `object` using the specified `hashAlgorithm`.
379template <class HASHALG>
380void hashAppend(HASHALG& hashAlgorithm, const error_condition& object);
381
382// FREE OPERATORS
383
384/// Return whether the specified `lhs` and `rhs` are equal or equivalent.
385bool operator==(const error_code& lhs, const error_code& rhs);
386bool operator==(const error_code& lhs, const error_condition& rhs);
387bool operator==(const error_condition& lhs, const error_code& rhs);
388bool operator==(const error_condition& lhs, const error_condition& rhs);
389
390/// Return whether the specified `lhs` and `rhs` are not equal or equivalent.
391bool operator!=(const error_code&, const error_code&);
392bool operator!=(const error_code&, const error_condition&);
393bool operator!=(const error_condition&, const error_code&);
394bool operator!=(const error_condition&, const error_condition&);
395
396/// Return whether the specified `lhs` is lexicographically less than the
397/// specified `rhs`, ordered by category then value.
398bool operator<(const error_code& lhs, const error_code& rhs);
399bool operator<(const error_condition& lhs, const error_condition& rhs);
400
401/// Write the specified `code` to `stream`.
402template <class CHAR_TYPE, class CHAR_TRAITS>
403inline
404std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& operator<<(
405 std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
406 const error_code& code);
407
408// ============================================================================
409// INLINE DEFINITIONS
410// ============================================================================
411
412 // --------------------
413 // class error_category
414 // --------------------
415
416//CREATORS
417inline
418error_category::error_category()
419{
420}
421
422// ACCESSORS
423inline
424error_condition error_category::default_error_condition(
425 int value) const BSLS_KEYWORD_NOEXCEPT
426{
427 return error_condition(value, *this);
428}
429
430inline
431bool error_category::equivalent(
432 int code,
433 const error_condition& condition) const BSLS_KEYWORD_NOEXCEPT
434{
435 return default_error_condition(code) == condition;
436}
437
438inline
439bool error_category::equivalent(
440 const error_code& code,
441 int condition) const BSLS_KEYWORD_NOEXCEPT
442{
443 return *this == code.category() && code.value() == condition;
444}
445
446inline
447std::string error_category::message(int value) const
448{
449 return strerror(value);
450}
451
452inline
453const char *error_category::name() const BSLS_KEYWORD_NOEXCEPT
454{
455 return "error_category";
456}
457
458inline
459bool error_category::operator==(
460 const error_category& other) const BSLS_KEYWORD_NOEXCEPT
461{
462 return this == &other;
463}
464
465inline
466bool error_category::operator!=(
467 const error_category& other) const BSLS_KEYWORD_NOEXCEPT
468{
469 return !(*this == other);
470}
471
472inline
473bool error_category::operator<(
474 const error_category& other) const BSLS_KEYWORD_NOEXCEPT
475{
476 return std::less<const error_category *>()(this, &other);
477}
478
479 // ----------------
480 // class error_code
481 // ----------------
482
483// CREATORS
484inline
485error_code::error_code()
486: d_value(0)
487, d_category_p(&system_category())
488{
489}
490
491inline
492error_code::error_code(int value, const error_category& category)
493: d_value(value)
494, d_category_p(&category)
495{
496}
497
498template <class ERROR_CODE_ENUM>
499inline
500error_code::error_code(ERROR_CODE_ENUM value,
501 typename enable_if<
502 is_error_code_enum<ERROR_CODE_ENUM>::value,
503 BoolType>::type) // IMPLICIT
504: d_value(make_error_code(value).value())
505, d_category_p(&make_error_code(value).category())
506{
507}
508
509
510// MANIPULATORS
511inline
512void error_code::assign(int value, const error_category& category)
513{
514 d_value = value;
515 d_category_p = &category;
516}
517
518inline
519void error_code::clear()
520{
521 d_value = 0;
522 d_category_p = &system_category();
523}
524
525template <class ERROR_CODE_ENUM>
526inline
527typename enable_if<is_error_code_enum<ERROR_CODE_ENUM>::value,
528 error_code&>::type
529error_code::operator=(ERROR_CODE_ENUM value)
530{
531 d_value = make_error_code(value).value();
532 d_category_p = &make_error_code(value).category();
533 return *this;
534}
535
536// ACCESSORS
537inline
538const error_category& error_code::category() const
539{
540 return *d_category_p;
541}
542
543inline
544error_condition error_code::default_error_condition() const
545{
546 return category().default_error_condition(value());
547}
548
549inline
550std::string error_code::message() const
551{
552 return category().message(value());
553}
554
555inline
556int error_code::value() const
557{
558 return d_value;
559}
560
561inline
562error_code::operator BoolType() const
563{
564 return UnspecifiedBool::makeValue(value());
565}
566
567// FREE FUNCTIONS
568template <class HASHALG>
569void hashAppend(HASHALG& hashAlgorithm, const error_code& object)
570{
571 using ::BloombergLP::bslh::hashAppend;
572 hashAppend(hashAlgorithm, static_cast<const void *>(&object.category()));
573 hashAppend(hashAlgorithm, object.value());
574}
575
576inline
577error_code make_error_code(errc::Enum value)
578{
579 return error_code(static_cast<int>(value), generic_category());
580}
581
582// FREE OPERATORS
583template <class CHAR_TYPE, class CHAR_TRAITS>
584inline
585std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& operator<<(
586 std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& stream,
587 const error_code& code)
588{
589 return stream << code.category().name() << ':' << code.value();
590}
591
592 // ---------------------
593 // class error_condition
594 // ---------------------
595
596// CREATORS
597inline
598error_condition::error_condition()
599: d_value(0)
600, d_category_p(&generic_category())
601{
602}
603
604inline
605error_condition::error_condition(int value, const error_category& category)
606: d_value(value)
607, d_category_p(&category)
608{
609}
610
611template <class ERROR_CONDITION_ENUM>
612inline
613error_condition::error_condition(
614 ERROR_CONDITION_ENUM value,
615 typename enable_if<is_error_condition_enum<ERROR_CONDITION_ENUM>::value,
616 BoolType>::type) // IMPLICIT
617: d_value(make_error_condition(value).value())
618, d_category_p(&make_error_condition(value).category())
619{
620}
621
622// MANIPULATORS
623inline
624void error_condition::assign(int value, const error_category& category)
625{
626 d_value = value;
627 d_category_p = &category;
628}
629
630inline
631void error_condition::clear()
632{
633 d_value = 0;
634 d_category_p = &generic_category();
635}
636
637template <class ERROR_CONDITION_ENUM>
638inline
639typename enable_if<is_error_condition_enum<ERROR_CONDITION_ENUM>::value,
640 error_condition&>::type
641error_condition::operator=(ERROR_CONDITION_ENUM value)
642{
643 d_value = make_error_condition(value).value();
644 d_category_p = &make_error_condition(value).category();
645 return *this;
646}
647
648// ACCESSORS
649inline
650const error_category& error_condition::category() const
651{
652 return *d_category_p;
653}
654
655inline
656std::string error_condition::message() const
657{
658 return category().message(value());
659}
660
661inline
662int error_condition::value() const
663{
664 return d_value;
665}
666
667inline
668error_condition::operator BoolType() const
669{
670 return UnspecifiedBool::makeValue(value());
671}
672
673// FREE FUNCTIONS
674template <class HASHALG>
675void hashAppend(HASHALG& hashAlgorithm, const error_condition& object)
676{
677 using ::BloombergLP::bslh::hashAppend;
678 hashAppend(hashAlgorithm, static_cast<const void *>(&object.category()));
679 hashAppend(hashAlgorithm, object.value());
680}
681
682inline
683error_condition make_error_condition(errc::Enum value)
684{
685 return error_condition(static_cast<int>(value), generic_category());
686}
687
688// FREE OPERATORS
689inline
690bool operator==(const error_code& lhs, const error_code& rhs)
691{
692 return lhs.category() == rhs.category() && lhs.value() == rhs.value();
693}
694
695inline
696bool operator==(const error_code& lhs, const error_condition& rhs)
697{
698 return lhs.category().equivalent(lhs.value(), rhs) ||
699 rhs.category().equivalent(lhs, rhs.value());
700}
701
702inline
703bool operator==(const error_condition& lhs, const error_code& rhs)
704{
705 return rhs.category().equivalent(rhs.value(), lhs) ||
706 lhs.category().equivalent(rhs, lhs.value());
707}
708
709inline
710bool operator==(const error_condition& lhs, const error_condition& rhs)
711{
712 return lhs.category() == rhs.category() && lhs.value() == rhs.value();
713}
714
715inline
716bool operator!=(const error_code& lhs, const error_code& rhs)
717{
718 return !(lhs == rhs);
719}
720
721inline
722bool operator!=(const error_code& lhs, const error_condition& rhs)
723{
724 return !(lhs == rhs);
725}
726
727inline
728bool operator!=(const error_condition& lhs, const error_code& rhs)
729{
730 return !(lhs == rhs);
731}
732
733inline
734bool operator!=(const error_condition& lhs, const error_condition& rhs)
735{
736 return !(lhs == rhs);
737}
738
739inline
740bool operator<(const error_code& lhs, const error_code& rhs)
741{
742 return lhs.category() < rhs.category() ||
743 (lhs.category() == rhs.category() && lhs.value() < rhs.value());
744}
745
746inline
747bool operator<(const error_condition& lhs, const error_condition& rhs)
748{
749 return lhs.category() < rhs.category() ||
750 (lhs.category() == rhs.category() && lhs.value() < rhs.value());
751}
752
753template <>
754struct hash<bsl::error_code> : BloombergLP::bslh::Hash<>
755{
756};
757
758template <>
759struct hash<bsl::error_condition> : BloombergLP::bslh::Hash<>
760{
761};
762
763} // close namespace bsl
764
765namespace std {
766
767#if !defined(BSLS_PLATFORM_OS_DARWIN) || defined (BSLS_PLATFORM_CMP_GNU)
768 // On C++03 on Darwin, the template struct 'hash' is forward declared with
769 // different attributes in <typetraits> that conflict with this forward
770 // declaration.
771
772 template <class TYPE>
773 struct hash;
774#endif
775
776template <>
777struct hash<bsl::error_code> : BloombergLP::bslh::Hash<>
778{
779};
780
781template <>
782struct hash<bsl::error_condition> : BloombergLP::bslh::Hash<>
783{
784};
785} // close namespace std
786
787#endif
788#endif
789
790// ----------------------------------------------------------------------------
791// Copyright 2019 Bloomberg Finance L.P.
792//
793// Licensed under the Apache License, Version 2.0 (the "License");
794// you may not use this file except in compliance with the License.
795// You may obtain a copy of the License at
796//
797// http://www.apache.org/licenses/LICENSE-2.0
798//
799// Unless required by applicable law or agreed to in writing, software
800// distributed under the License is distributed on an "AS IS" BASIS,
801// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
802// See the License for the specific language governing permissions and
803// limitations under the License.
804// ----------------------------- END-OF-FILE ----------------------------------
805
806/** @} */
807/** @} */
808/** @} */
bsl::ostream & operator<<(bsl::ostream &stream, const bdlat_AttributeInfo &attributeInfo)
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
bool operator<(const MetricId &lhs, const MetricId &rhs)
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlb_printmethods.h:283
Definition bdldfp_decimal.h:5188