Click here to Skip to main content
15,884,099 members
Articles / Database Development / SQL Server

CLinq - LINQ support for the C++/CLI language

Rate me:
Please Sign up or sign in to vote.
4.86/5 (22 votes)
27 Jul 2007Ms-PL19 min read 64K   1.1K   37  
CLinq project is a library that makes it possible to use LINQ technologies from the C++/CLI language
#pragma once
#include "clinqcore.h"
#include "clinqtyped.h"
#include "clinqseq.h"

using namespace System;
using namespace System::Reflection;
using namespace System::Collections::Generic;

namespace EeekSoft
{
	namespace CLinq
	{
		namespace clq
		{
			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 1 argument
			/// and body and returns lambda expression. 
			/// When using Expr as parameters, the type inferrence infers generic arguments.
			/// </summary>
			template<class A0, class T> 
			Lambda<System::Query::Func<A0, T>^>^ fun(Expr<A0> v, Expr<T> body)
			{
				return gcnew Lambda<System::Query::Func<A0, T>^>(gcnew array<GenericExpression^>{ v }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 2 arguments 
			/// and body and returns lambda expression.
			/// When using Expr as parameters, the type inferrence infers generic arguments.
			/// </summary>
			template<class A0, class A1, class T>
			Lambda<System::Query::Func<A0, A1, T>^>^ fun(Expr<A0> v0, Expr<A1> v1, Expr<T> body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, T>^>(gcnew array<GenericExpression^>{ v0, v1 }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 3 arguments 
			/// and body and returns lambda expression.
			/// When using Expr as parameters, the type inferrence infers generic arguments.
			/// </summary>
			template<class A0, class A1, class A2, class T>
			Lambda<System::Query::Func<A0, A1, A2, T>^>^ fun(Expr<A0> v0, Expr<A1> v1, Expr<A2> v2, Expr<T> body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, A2, T>^>(gcnew array<GenericExpression^>{ v0, v1, v2 }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 4 arguments 
			/// and body and returns lambda expression.
			/// When using Expr as parameters, the type inferrence infers generic arguments.
			/// </summary>
			template<class A0, class A1, class A2, class A3, class T>
			Lambda<System::Query::Func<A0, A1, A2, A3, T>^>^ fun(Expr<A0> v0, Expr<A1> v1, Expr<A2> v2, Expr<A3> v3, Expr<T> body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, A2, A3, T>^>(gcnew array<GenericExpression^>{ v0, v1, v2, v3 }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 1 argument
			/// and body and returns lambda expression.
			/// </summary>
			template<class A0, class T> 
			Lambda<System::Query::Func<A0, T>^>^ fun(Expression<A0>^ v, Expression<T>^ body)
			{
				return gcnew Lambda<System::Query::Func<A0, T>^>(gcnew array<GenericExpression^>{ v }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 2 arguments 
			/// and body and returns lambda expression.
			/// </summary>
			template<class A0, class A1, class T>
			Lambda<System::Query::Func<A0, A1, T>^>^ fun(Expression<A0>^ v0, Expression<A1>^ v1, Expression<T>^ body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, T>^>(gcnew array<GenericExpression^>{ v0, v1 }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 3 arguments 
			/// and body and returns lambda expression.
			/// </summary>
			template<class A0, class A1, class A2, class T>
			Lambda<System::Query::Func<A0, A1, A2, T>^>^ fun(Expression<A0>^ v0, Expression<A1>^ v1, Expression<A2>^ v2, Expression<T>^ body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, A2, T>^>(gcnew array<GenericExpression^>{ v0, v1, v2 }, body);
			}

			/// <summary>
			/// Function for declaring lambda expressions. Takes expressions representing 4 arguments 
			/// and body and returns lambda expression.
			/// </summary>
			template<class A0, class A1, class A2, class A3, class T>
			Lambda<System::Query::Func<A0, A1, A2, A3, T>^>^ fun(Expression<A0>^ v0, Expression<A1>^ v1, Expression<A2>^ v2, Expression<A3>^ v3, Expression<T>^ body)
			{
				return gcnew Lambda<System::Query::Func<A0, A1, A2, A3, T>^>(gcnew array<GenericExpression^>{ v0, v1, v2, v3 }, body);
			}

			/// <summary>
			/// Represents creation of an object instance. Type parameter specifies class to be created and parameters will be
			/// passed as an arguments to constructor. Constructor with the same number of parameters will be selected.
			/// </summary>
			/// <remarks>
			/// Throws CLinqException if the constructor with specified number of arguments doesn't exist or is ambigous.
			/// </remarks>
			template<class T>
			Expr<T> newobj(... array<GenericExpression^>^ args)
			{
				Type^ t = T::typeid;

				ConstructorInfo^ selected = nullptr;
				for each(ConstructorInfo^ c in t->GetConstructors())
				{
					if (c->GetParameters()->Length == args->Length) 
					{
						if (selected == nullptr)
							selected = c;
						else 
							throw gcnew Exception("Ambigous constructor found!");
					}
				}
				if (selected == nullptr)
					throw gcnew Exception("No constructor with specified number of parameters found!");
				return Expr<T>(gcnew ConstructorInvokeExpression<T>(selected, args));
			}

			/// <summary>
			/// Represents conversion between expressions of two different types.
			/// </summary>
			template<class T>
			Expr<T> conv(GenericExpression^ expr)
			{
				return Expr<T>::Convert(expr);
			}

			/// <summary>
			/// Returns same expression that is passed as a parameter, but with type information.
			/// Use this method if you have untyped expression and you want to convert it to typed expression.
			/// </summary>
			template<class T>
			Expr<T> typed(GenericExpression^ expr)
			{
				return Expr<T>::Typed(expr);
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Czech Republic Czech Republic
I live in Prague, the capital city of Czech republic (most of the time Smile | :) ). I've been very interested in functional programming recently and I have a passion for the new Microsoft F# language. I'm writing a book about Functional Programming in the Real World that shows the ideas using examples in C# 3.0 and F#.

I've been Microsoft MVP (for C#) since 2004 and I'm one of the most active members of the F# community. I'm a computer science student at Charles University of Prague. My hobbies include photography, fractals and of course many things related to computers (except fixing them). My favorite book writers are Terry Pratchett and Philip K Dick and I like paintings by M. C. Escher.

PS: My favorite codeproject icon is Sheep | [baah] .

Comments and Discussions