File indexing completed on 2025-10-12 04:59:54
0001 // bjgb_rank.h -*-C++-*- 0002 #ifndef INCLUDED_BJGB_RANK 0003 #define INCLUDED_BJGB_RANK 0004 0005 //@PURPOSE: Enumerate the distinct ranks (values) of cards in blackjack. 0006 // 0007 //@CLASSES: 0008 // bjgb::Rank: class representing the ranks of blackjack cards 0009 // 0010 //@DESCRIPTION: This component provides a class, 'bjgb::Rank', and its 0011 // associated user-defined literal (UDL) operator that enumerate the ten 0012 // distinct card ranks (or values) in blackjack. 0013 // 0014 /// Literals 0015 ///-------- 0016 //.. 0017 // Name Value 0018 // ---- -------------------------------------------- 0019 // A_R 1 (Ace; alias for 1_R) 0020 // 2_R 2 0021 // 3_R 3 0022 // 4_R 4 0023 // 5_R 5 0024 // 6_R 6 0025 // 7_R 7 0026 // 8_R 8 0027 // 9_R 9 0028 // T_R 10 (Ten, Jack, Queen, King; alias for 10_R) 0029 //.. 0030 // 0031 // Iteration over the ranks is supported by member function 'operator++()', 0032 // free 'operator<', and the 'end' class method. 0033 // 0034 /// Usage 0035 ///----- 0036 // Iterate over the range of ranks and print each: 0037 //.. 0038 // for (Rank r = A_R; r != Rank::end(); ++r) { 0039 // if (r != A_R) { 0040 // std::cout << ' '; 0041 // } 0042 // std::cout << r; 0043 // } 0044 // 0045 // std::cout << '\n'; 0046 //.. 0047 // The above prints the following to 'std::cout': 0048 //.. 0049 // A 2 3 4 5 6 7 8 9 T 0050 //.. 0051 0052 #include <cassert> 0053 #include <iosfwd> 0054 0055 namespace bjgb { 0056 0057 class Rank; 0058 0059 // UDL OPERATORS 0060 inline namespace literals { 0061 inline namespace RankLiterals { 0062 constexpr Rank operator""_R(unsigned long long value); 0063 } // namespace RankLiterals 0064 } // namespace literals 0065 0066 // ========== 0067 // class Rank 0068 // ========== 0069 0070 class Rank { 0071 // This class represents the ranks of cards in blackjack. Instances of 0072 // this class can be created only via either the associated UDL operator, 0073 // '_R', or the 'end' class method. 0074 0075 // DATA 0076 int d_value; // the range '[1 .. 10]' corresponds to A, 2, ..., T; 11 is 0077 // used to represent the one-past-the-end value for iterating 0078 0079 // FRIENDS 0080 friend constexpr Rank RankLiterals::operator""_R(unsigned long long); 0081 friend bool operator==(const Rank&, const Rank&); 0082 friend bool operator!=(const Rank&, const Rank&); 0083 friend bool operator<(const Rank&, const Rank&); 0084 0085 private: 0086 // PRIVATE CREATORS 0087 explicit constexpr Rank(int value); 0088 // Create a rank object having the specified 'value'. The behavior is 0089 // undefined unless '1 <= value' and 'value <= 11'. Note that 0090 // 'Rank(11)' provides the value for 'Rank::end()'. 0091 0092 public: 0093 // CLASS METHODS 0094 static Rank end(); 0095 // Return a rank object having the one-past-the-end value. 0096 0097 // CREATORS 0098 Rank() = delete; 0099 0100 Rank(const Rank& original) = default; 0101 // Create a rank object having the same value as that of the specified 0102 // 'original' object. 0103 0104 ~Rank() = default; 0105 // Destroy this rank object. 0106 0107 // MANIPULATORS 0108 Rank& operator=(const Rank& rhs) = default; 0109 // Assign to this object the value of the specified 'rhs' rank, and 0110 // return a reference providing modifiable access to this object. 0111 0112 Rank& operator++(); 0113 // Increment this rank and return a non-'const' reference to this 0114 // object. The behavior is undefined unless '*this < Rank::end()' on 0115 // entry. Note that, for example: 0116 //.. 0117 // ++(5_R) == 6_R && ++(T_R) == Rank::end(); 0118 //.. 0119 0120 // ACCESSORS 0121 int value() const; 0122 // Return the integral value of this rank. The behavior is undefined 0123 // unless '*this != Rank::end()'. 0124 }; 0125 0126 // FREE OPERATORS 0127 bool operator==(const Rank& lhs, const Rank& rhs); 0128 // Return 'true' if the specified 'lhs' and 'rhs' ranks have the same 0129 // value, and 'false' otherwise. Two 'Rank' objects have the same value if 0130 // they correspond to the same UDL in the range '[A_R .. T_R]' or both have 0131 // the same value as 'Rank::end()'. 0132 0133 bool operator!=(const Rank& lhs, const Rank& rhs); 0134 // Return 'true' if the specified 'lhs' and 'rhs' ranks do not have the 0135 // same value, and 'false' otherwise. Two 'Rank' objects do not have the 0136 // same value if they correspond to different UDLs in the range 0137 // '[A_R .. T_R]' or one of them, but not both, has the same value as 0138 // 'Rank::end()'. 0139 0140 bool operator<(const Rank& lhs, const Rank& rhs); 0141 // Return 'true' if the specified 'lhs' rank is less than the specified 0142 // 'rhs' rank, and 'false' otherwise. All ranks corresponding to UDLs in 0143 // the range '[A_R .. T_R]' compare less than 'Rank::end()'. 0144 0145 std::ostream& operator<<(std::ostream& stream, const Rank& rank); 0146 // Write the string representation of the specified 'rank' to the specified 0147 // output 'stream' in a single-line format, and return a reference to 0148 // 'stream'. 0149 0150 // ============================================================================ 0151 // INLINE DEFINITIONS 0152 // ============================================================================ 0153 0154 // ---------- 0155 // class Rank 0156 // ---------- 0157 0158 // PRIVATE CREATORS 0159 inline constexpr Rank::Rank(int value): d_value(value) 0160 { 0161 assert(1 <= value); 0162 assert(value <= 11); 0163 } 0164 0165 // CLASS METHODS 0166 inline Rank Rank::end() 0167 { 0168 return Rank(11); 0169 } 0170 0171 // MANIPULATORS 0172 inline Rank& Rank::operator++() 0173 { 0174 assert(d_value <= 10); 0175 0176 ++d_value; 0177 0178 return *this; 0179 } 0180 0181 // ACCESSORS 0182 inline int Rank::value() const 0183 { 0184 assert(d_value <= 10); 0185 0186 return d_value; 0187 } 0188 0189 } // namespace bjgb 0190 0191 // FREE OPERATORS 0192 inline bool bjgb::operator==(const Rank& lhs, const Rank& rhs) 0193 { 0194 return lhs.d_value == rhs.d_value; 0195 } 0196 0197 inline bool bjgb::operator!=(const Rank& lhs, const Rank& rhs) 0198 { 0199 return lhs.d_value != rhs.d_value; 0200 } 0201 0202 inline bool bjgb::operator<(const Rank& lhs, const Rank& rhs) 0203 { 0204 return lhs.d_value < rhs.d_value; 0205 } 0206 0207 // UDL OPERATORS 0208 inline constexpr bjgb::Rank bjgb::RankLiterals::operator""_R(unsigned long long value) 0209 { 0210 assert(1 <= value); 0211 assert(value <= 10); 0212 0213 return Rank(value); 0214 } 0215 0216 namespace bjgb { 0217 inline namespace literals { 0218 inline namespace RankLiterals { 0219 constexpr Rank A_R = 1_R; 0220 constexpr Rank T_R = 10_R; 0221 } // namespace RankLiterals 0222 } // namespace literals 0223 } // namespace bjgb 0224 0225 #endif