Created
November 28, 2012 21:29
-
-
Save jbandela/4164700 to your computer and use it in GitHub Desktop.
Select a template class based on a string
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
// 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