A high-performance C++17 library for working with standard 52-card decks. Designed for card game implementations, simulations, and poker hand evaluators.
- Immutable Card Primitives:
Suit,Rank, andCardare singleton objects with compile-time constant access - Bitmask-Based Operations: Cards are represented as 64-bit bitmasks enabling O(1) set operations
- Full Deck Management: Shuffle, deal, cut, and manipulate decks with ease
- Iterator Support: Range-based for loops and STL algorithm compatibility
- Zero-Copy Design: Card references avoid unnecessary allocations
#include <cards/cards.h>
#include <cards/deck.h>
#include <iostream>
using namespace cards;
int main() {
// Create and shuffle a deck
Deck deck;
deck.shuffle();
// Deal 5 cards (returns bitmask of dealt cards)
uint64_t hand = deck.deal_cards(5);
// Access individual cards
std::cout << Card::CAS.name() << std::endl; // "Ace of Spades"
std::cout << Card::CAS.symbol() << std::endl; // "A♠"
// Check card properties
const Card& card = Card::CKH;
std::cout << card.rank().name() << std::endl; // "King"
std::cout << card.suit().name() << std::endl; // "Heart"
return 0;
}# Add as subdirectory
add_subdirectory(libcards)
target_link_libraries(your_target PRIVATE cards)mkdir build && cd build
cmake ..
make
make install| Document | Description |
|---|---|
| Getting Started | Installation, setup, and basic concepts |
| Suit | Suit class reference (Club, Diamond, Heart, Spade) |
| Rank | Rank class reference (Two through Ace) |
| Card | Card class reference (all 52 cards) |
| Deck | Deck class reference (shuffling, dealing, manipulation) |
| Internals | Bitmask representation and optimization techniques |
| Examples | Complete examples for common use cases |
Access any card directly using the naming convention C{Rank}{Suit}:
Card::CAS // Ace of Spades
Card::CKH // King of Hearts
Card::C2C // Two of Clubs
Card::CTD // Ten of DiamondsDeck deck;
// Shuffle and deal
deck.shuffle();
uint64_t hand = deck.deal_cards(5);
// Deck manipulation
deck.cut(26); // Cut at position 26
deck.reverse(); // Reverse card order
// Peek without dealing
uint64_t next = deck.peek(1);
const Card& top = deck.top_card();
// Check state
bool empty = deck.is_empty();
int remaining = deck.count();Cards use bitmask representation for efficient set operations:
// Combine cards into a bitmask
uint64_t hand = Card::mask(Card::CAS, Card::CKS, Card::CQS, Card::CJS, Card::CTS);
// Format cards as symbols
std::cout << Card::format(hand) << std::endl; // "T♠ J♠ Q♠ K♠ A♠"
// Parse cards from string (supports various formats)
auto parsed = Card::parse("As Ks Qs Js Ts"); // Also: "AsKs", "As,Ks", "A♠ K♠"
if (parsed) {
std::cout << Card::format(*parsed) << std::endl;
}
// Extract cards from a bitmask
auto cards = Card::extract(hand);
for (const auto& card : cards) {
std::cout << card.get().name() << std::endl;
}
// Check containment
bool has_ace = (hand & Card::CAS.key()) != 0;
// Count cards (population count)
int count = __builtin_popcountll(hand);- C++17 or later
- CMake 3.14+ (for building)
- GCC 7+, Clang 5+, or MSVC 2017+
Source-Available License - Free to use, restrictions on copying/redistribution. See LICENSE for details.
Found a bug or have a feature request? Please open an issue. See CONTRIBUTING.md for guidelines.