Skip to content

Commit e4f2076

Browse files
committed
Trivial Currency Tags
- trivially copyable - lightweight - implicitly constructible from `string_view`
1 parent 7248c9c commit e4f2076

3 files changed

Lines changed: 72 additions & 14 deletions

File tree

cdr/swaps/irs.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void IrsContract::ApplyCurve(const Curve& curve) noexcept {
7878

7979
/* IrsBuilder */
8080

81-
[[nodiscard]] IrsContract IrsBuilder::Build(const HolidayStorage& hs, const JurisdictionType& jur, DateRollingRule rule) {
81+
[[nodiscard]] IrsContract IrsBuilder::Build(const HolidayStorage& hs, JurisdictionType jur, DateRollingRule rule) {
8282

8383
CDR_CHECK(maturity_date_.has_value()) << "must be defined";
8484
CDR_CHECK(settlement_date_.has_value()) << "must be defined";
@@ -88,10 +88,9 @@ void IrsContract::ApplyCurve(const Curve& curve) noexcept {
8888
CDR_CHECK(paying_fix_.has_value()) << "must be defined";
8989
CDR_CHECK(fixed_freq_.has_value()) << "must be defined";
9090
CDR_CHECK(float_freq_.has_value()) << "must be defined";
91-
CDR_CHECK(!jur.empty()) << "must be non-empty";
9291

9392
static constexpr u32 kRandomReservationConstant = 10;
94-
IrsContract result(fixed_rate_.value(), paying_fix_.value());
93+
IrsContract result(jur, fixed_rate_.value(), paying_fix_.value());
9594

9695
std::vector<IrsPaymentPeriod> sched;
9796
sched.reserve(kRandomReservationConstant);
@@ -159,7 +158,6 @@ void IrsContract::ApplyCurve(const Curve& curve) noexcept {
159158
sched[last].chrono_next_idx_ = curr;
160159
}
161160

162-
result.jurisdiction_ = jur;
163161
result.chrono_last_idx_ = last;
164162
result.notional_ = *notional_;
165163
result.payment_periods_ = std::move(sched);
@@ -184,7 +182,7 @@ void IrsBuilder::Reset() {
184182

185183
/* IrsBuilderExperimental */
186184

187-
[[nodiscard]] IrsContract IrsBuilderExperimental::Build(const HolidayStorage& hs, const JurisdictionType& jur, DateRollingRule rule) {
185+
[[nodiscard]] IrsContract IrsBuilderExperimental::Build(const HolidayStorage& hs, JurisdictionType jur, DateRollingRule rule) {
188186

189187
CDR_CHECK(trade_date_.has_value()) << "must be defined";
190188
CDR_CHECK(start_shift_.has_value()) << "must be defined";
@@ -197,12 +195,11 @@ void IrsBuilder::Reset() {
197195
CDR_CHECK(adjustment_.has_value()) << "must be defined";
198196
CDR_CHECK(notional_.has_value()) << "must be defined";
199197
CDR_CHECK(paying_fix_.has_value()) << "must be defined";
200-
CDR_CHECK(!jur.empty()) << "must be non-empty";
201198

202199
CDR_CHECK(fixed_freq_->number > 0) << "must be positive";
203200
CDR_CHECK(float_freq_->number > 0) << "must be positive";
204201

205-
IrsContract result(fixed_rate_.value_or(Percent::Zero()), *paying_fix_);
202+
IrsContract result(jur, fixed_rate_.value_or(Percent::Zero()), *paying_fix_);
206203
std::vector<IrsPaymentPeriod> sched;
207204

208205
// --------- fixed leg ------------
@@ -271,7 +268,6 @@ void IrsBuilder::Reset() {
271268

272269
// -------------------------------
273270

274-
result.jurisdiction_ = jur;
275271
result.payment_periods_ = std::move(sched);
276272
result.fixed_leg_ = result.payment_periods_.data();
277273
result.float_leg_ = result.payment_periods_.data() + float_begin;

cdr/swaps/irs.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ class CDR_SWAPS_EXPORT IrsContract final {
121121

122122
private:
123123

124-
IrsContract(Percent fixed_rate, bool paying_fix)
125-
: fixed_rate_(fixed_rate)
124+
IrsContract(JurisdictionType jurisdiction, Percent fixed_rate, bool paying_fix)
125+
: jurisdiction_(jurisdiction)
126+
, fixed_rate_(fixed_rate)
126127
, paying_fix_(paying_fix)
127128
{}
128129

@@ -194,7 +195,7 @@ class CDR_SWAPS_EXPORT IrsBuilder final {
194195
return *this;
195196
}
196197

197-
[[nodiscard]] IrsContract Build(const HolidayStorage& hs, const std::string& jur,
198+
[[nodiscard]] IrsContract Build(const HolidayStorage& hs, JurisdictionType jur,
198199
DateRollingRule rule = DateRollingRule::kFollowing);
199200

200201
void Reset();
@@ -273,7 +274,7 @@ class CDR_SWAPS_EXPORT IrsBuilderExperimental {
273274
return *this;
274275
}
275276

276-
[[nodiscard]] IrsContract Build(const HolidayStorage& hs, const std::string& jur,
277+
[[nodiscard]] IrsContract Build(const HolidayStorage& hs, JurisdictionType jur,
277278
DateRollingRule rule = DateRollingRule::kFollowing);
278279

279280
void Reset();

cdr/types/jurisdiction.h

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,67 @@
11
#pragma once
22

3-
#include <string>
3+
#include <cdr/types/types.h>
4+
#include <cdr/base/check.h>
5+
6+
#include <algorithm>
7+
#include <bit>
8+
#include <string_view>
9+
#include <ostream>
10+
#include <charconv>
11+
#include <cstring>
12+
#include <iostream>
13+
14+
namespace stdr = std::ranges;
15+
16+
class CurrencyTag {
17+
public:
18+
// implicit
19+
constexpr CurrencyTag(const char* str) noexcept: data_{} {
20+
size_t str_size = std::char_traits<char>::length(str);
21+
22+
// NOTE: CDR_CHECK is not constexpr
23+
if (str_size >= 8) [[unlikely]] {
24+
std::cerr << "Fatal: currency tag too long: " << str << std::endl;
25+
std::terminate();
26+
}
27+
stdr::copy_n(str, str_size, data_);
28+
}
29+
30+
constexpr std::string_view Str() const noexcept {
31+
return data_;
32+
}
33+
34+
constexpr bool operator==(CurrencyTag other) const noexcept {
35+
return stdr::equal(data_, other.data_);
36+
}
37+
38+
constexpr bool operator<(CurrencyTag other) const noexcept {
39+
return std::bit_cast<u64>(*this) < std::bit_cast<u64>(other);
40+
}
41+
42+
private:
43+
alignas(8) char data_[8];
44+
};
45+
46+
inline std::ostream& operator<<(std::ostream& os, CurrencyTag tag) {
47+
return os << tag.Str();
48+
}
49+
50+
namespace std {
51+
52+
template <>
53+
struct hash<CurrencyTag> {
54+
hash<u64> hashfunc_;
55+
u64 operator()(CurrencyTag tag) const noexcept {
56+
return hashfunc_(std::bit_cast<u64>(tag));
57+
}
58+
};
59+
60+
} // namespace std
61+
62+
63+
static_assert(sizeof(std::hash<CurrencyTag>) == 1);
64+
static_assert(sizeof(CurrencyTag) == 8);
65+
static_assert(std::is_trivially_copyable_v<CurrencyTag>);
466

5-
using CurrencyTag = std::string;
667
using JurisdictionType = CurrencyTag;

0 commit comments

Comments
 (0)