1 module dnv.error; 2 3 import std.conv : to; 4 import std.string : format, split; 5 import std.algorithm : findSplitAfter; 6 import std.range : retro; 7 8 9 auto findLast(R1, R2)(R1 haystack, R2 needle) { 10 return haystack.retro 11 .findSplitAfter(needle.retro)[0] 12 .to!R1.retro; 13 } 14 15 auto findBetween(R1, R2)(R1 haystack, R2 start, R2 end) { 16 // NOTE: this extract first found `end` to backward nearest `start` 17 // including both corner ranges. 18 return haystack.findSplitAfter(end)[0] 19 .findLast(start); 20 } 21 22 unittest { 23 assert(findLast("abcdefg abc", "ab").to!string == "abc"); 24 assert(findBetween("a abcdefg bc", "a", "bc").to!string == "abc"); 25 } 26 27 28 enum CImportEnum(string name, string headerPath) = function(){ 29 enum start = "typedef enum"; 30 enum header = import(headerPath); 31 enum end = "} " ~ name ~ ";"; 32 enum cdef = findBetween(header, start, end).to!string; 33 enum content = cdef.findSplitAfter("{")[1].findSplitAfter("}")[0]; 34 return "extern (C++) enum %s : int {%s".format(name, content); 35 }(); 36 37 mixin(CImportEnum!("CUresult", "cuda.h")); 38 mixin(CImportEnum!("nvrtcResult", "nvrtc.h")); 39 40 41 unittest { 42 static assert(CUresult.CUDA_ERROR_UNKNOWN == 999); 43 static assert(nvrtcResult.NVRTC_SUCCESS == 0); 44 } 45 46 47 class CudaError(Result) : Exception { 48 const Result result; 49 50 this(Result r, string file = __FILE__, int line = __LINE__) { 51 result = r; 52 super(toString, file, line); 53 } 54 55 override string toString() { 56 return Result.stringof ~ "." ~ result.to!string; 57 } 58 } 59 60 void check(Result, string file = __FILE__, int line = __LINE__)(Result result) { 61 if (result) { 62 throw new CudaError!Result(result, file, line); 63 } 64 } 65 66 void cuCheck(string file = __FILE__, int line = __LINE__)(int result) { 67 if (result) { 68 check!(CUresult, file, line)(cast(CUresult) result); 69 } 70 } 71 72 void nvrtcCheck(string file = __FILE__, int line = __LINE__)(int result) { 73 if (result) { 74 check!(nvrtcResult, file, line)(cast(nvrtcResult) result); 75 } 76 } 77 78 79 unittest { 80 import std.exception; 81 import dnv.storage; 82 import dnv.driver; 83 84 try { 85 check(CUresult.CUDA_ERROR_UNKNOWN); 86 } catch(CudaError!CUresult e) { 87 auto s = e.toString(); 88 assert(s == "CUresult.CUDA_ERROR_UNKNOWN"); 89 } 90 assertThrown(new Array!float(3, 100)); 91 }