Skip to content

Instantly share code, notes, and snippets.

@jbandela
Created November 28, 2012 21:29
Show Gist options
  • Save jbandela/4164700 to your computer and use it in GitHub Desktop.
Save jbandela/4164700 to your computer and use it in GitHub Desktop.
Select a template class based on a string
// For motivation see stackoverflow
// http://stackoverflow.com/questions/13612832/template-for-referencing-classes-themselves-rather-than-a-class-that-uses-templa
#include <iostream>
#include <string>
#include <typeinfo>
#include <cstring>
// The example uses CryptoAPI
// Below are some typedefs and dummy structures so we don't need cryptoapi just to test
typedef unsigned char byte;
struct DummyBase{
enum{DIGESTSIZE = 16};
void CalculateDigest( byte* , byte*, int){
}
};
struct MD5:DummyBase{};
struct SHA256:DummyBase{};
struct SHA512:DummyBase{};
template<class Digest, class... T>
struct DigestMatcher{
template<class U, class ... V>
static byte* doDigest(std::string input, int& digestSize,std::string algorithm,U firstalgorithm, U nextalgorithm, V... algorithms){
if(algorithm==firstalgorithm){
return doDigest(input,digestSize);
}
else{
return DigestMatcher<T...>::doDigest(input,digestSize,algorithm,nextalgorithm,algorithms...);
}
}
template<class U>
static byte* doDigest(std::string input, int& digestSize,std::string algorithm, U firstalgorithm){
if(algorithm==firstalgorithm){
return doDigest(input,digestSize);
}
else{
std::cout << algorithm << " invalid" << std::endl;
return 0;
}
}
static byte* doDigest(std::string input, int& digestSize){
// Cout for debug purposes
std::cout << "using " << typeid(Digest).name() << std::endl;
digestSize = Digest::DIGESTSIZE;
byte* digest = new byte[ digestSize ];
Digest().CalculateDigest( digest, (byte*) input.c_str(), input.length() );
return digest;
}
};
// A mock structure of the signagature class from the example
struct signatureAlgorithm{
void createDigest(std::string input);
std::string _algorithm;
int _digestSize;
byte* _digest;
bool _ready;
};
void signatureAlgorithm::createDigest(std::string input)
{
_digest = DigestMatcher<MD5,SHA256,SHA512>::doDigest(input,_digestSize,_algorithm,"md5","sha256","sha512");
if(_digest)
_ready = true;
else
_ready = false;
}
int main(){
std::string input;
signatureAlgorithm alg;
alg._algorithm = "sha256";
alg.createDigest(input);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment