Last active
January 23, 2017 22:47
-
-
Save scraimer/ad7bcdcd07f3899c47013ac84c825bc9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The flat_fix_parser I designed is good: | |
// Pro: | |
// * compile-time checking of fields | |
// * compact in memory, so less cache-thrashing | |
// Con: | |
// * doesn't support multiple copies of the same tag | |
// * fixed size in memory means there's no ability to handle unlimited number of tags | |
// | |
// To fix this, I want a more extensible design. Convert the FIX message into its hierarcy. | |
// For example, a V message that only has a repeating group of 269s within a 267: | |
// | |
// FIX | |
// 8=FIX.4.2 9=125 35=V 34=12 52=20130417-02:05:05.129 49=QUANTUMFX4601 | |
// 56=CNX 262=A 263=1 264=1 265=1 266=Y 146=1 55=EUR/USD | |
// 267=2 269=0 269=1 10=039 | |
// Should be modeled by: | |
// msg<8,9,35,34,52,49,56,262,263,264,265,266,146,55, | |
// group<267,3, 269>, 10 > | |
// | |
// The key points in this memory layout are: | |
// 1. the 'msg' template is simple: msg< tag_group<...>, repeating_groups<...> > | |
// 2. There can be more than one repeating group, since repeating_groups< repeating_group<...>, ... > | |
// 3. The tricky part is repeating_group< repeat_count_hint, tag1, tag2, ...> | |
// 3.1. The first param is 'repeat_count_hint' which say how many many tag_groups should be preallocated (i.e. how many times the user thinks the group repeats). If the user specified a number that's too low, we'll just allocate more, so it's not critical, but might have a performance hit.) | |
// 3.2. at compile time, you only specify a single tag_group of multiple tags, so it can do compile-time errors when reading undeclared tags | |
// 3.3. at run time, the tag_groups have to be chained together. Using the repeat_count_hint, the template will allocate extra items nearby in memory. They will all be chained together like a linked list to allow adding more items allocated at run-time without changing the code. So we'll allocate more as we parse, and chain them together in a linked list. | |
// (There a bunch of tricks we can do | |
// | |
// Although the memory layout should be more like this: | |
// | |
// msg< tag_group<8,9,35,34,52,49,56,262,263,264,265,266,146,55,10>, | |
// repeating_groups< | |
// repeating_group< 267, 3, | |
// tag_group<#, 269> | |
// tag_group<#, 269> | |
// > | |
// > | |
// > | |
// The problem is that I want to specify multiple different things in the arguments. | |
#include <cstddef> | |
template <int ... FIELDS > | |
class tag_group | |
{ | |
}; | |
template < int NUM_ITEMS_TAG, typename TAG_GROUP > | |
class repeating_group | |
{ | |
}; | |
template < typename REPEATING_GROUP1, typename ... REPEATING_GROUP > | |
class repeating_groups | |
{ | |
}; | |
template < typename TAG_GROUP, typename REPEATING_GROUPs = std::nullptr_t > | |
class msg | |
{ | |
}; | |
int main() | |
{ | |
msg< tag_group< 52, 262> > msg_with_only_tags; | |
msg< | |
tag_group< 52, 262 >, | |
repeating_groups< repeating_group<267, tag_group<269> > > | |
>p; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment