Skip to content

Instantly share code, notes, and snippets.

@scraimer
Last active January 23, 2017 22:47
Show Gist options
  • Save scraimer/ad7bcdcd07f3899c47013ac84c825bc9 to your computer and use it in GitHub Desktop.
Save scraimer/ad7bcdcd07f3899c47013ac84c825bc9 to your computer and use it in GitHub Desktop.
// 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