C++11 Unrestricted Union Copy Constructor - c++11

I would like to be able to use an unrestricted union as a simple value type, so I need a copy constructor. What is a safe way to make a copy constructor for an unrestricted union, i.e.:
union MyUnion
{
int m_int;
std::string m_str;
MyUnion() :
m_int(0)
{
}
MyUnion(const MyUnion & _other)
{
//?????
}
~MyUnion()
{
}
};
Is there any safe/easy way of implementing this? It appears to me that there is no safe way of making a copy without knowing if the _other union is either an integer or a string. Am I missing something?

Related

Is CTime nullable?

In a MFC application I like to map SQL date values (CDBVariant) to MFC CTime. Because the database entries can be NULL (value does not exist), I wonder if CTime is nullable. The remark in the MFC documentation to CTime::Format makes me thinking, it should be possible:
If the status of this CTime object is null, the return value is an empty string.
But how to set this status, is it even possible?
If it isn't possible, I guess boost::optional<CTime> would be a good alternative?
CTime is just a wrapper for a __time64_t. When you call format it does this:
inline CString CTime::Format(_In_z_ LPCTSTR pFormat) const
{
if(pFormat == NULL)
{
return pFormat;
}
TCHAR szBuffer[maxTimeBufferSize];
struct tm ptmTemp;
if (_localtime64_s(&ptmTemp, &m_time) != 0)
{
AtlThrow(E_INVALIDARG);
}
if (!_tcsftime(szBuffer, maxTimeBufferSize, pFormat, &ptmTemp))
{
szBuffer[0] = '\0';
}
return szBuffer;
}
So the system function you want to look at is _tcsftime. And this is where I think the documentation is not very accurate. If the _localtime64_s fails you'll get an exception so a 'null' time can't really be passed to _tcsftime. You'll only get a NULL if _tcsftime fails but that won't be because of a 'null' time.
So, in short, use something like you suggest of boost::optional to represent null.

Unable to create a constant value of type (type) Only primitive types ('such as Int32, String, and Guid') are supported in this context

I've read ALL of:
Unable to create a constant value of type 'System.Object' in Entity Framework
Entity Framework - "Unable to create a constant value of type 'Closure type'..." error
Entity Framework - Union causes "Unable to create a constant value of type.."
Only primitive types ('such as Int32, String, and Guid') are supported in this context
and searched a bit more, but still no solution. I've seen that this happens on EF 3.5 and in 4.0 the Contains method should be supported, but I'm in EF 4 but I'm getting this error. I have a photo gallery, where albums can have any number of different photos, and each photo can belong to any number of albums. So this is a many-to-many relationship.
I've got a VisibleObjects property which is used by about 100 other methods that work well, but I'm pasting it anyway: (I'm definitely sure the problem is not caused by something here)
static IQueryable<GlobalObject> VisibleObjects
{
get
{
return from obj in db.GlobalObjectSet where obj.IsVisible && !obj.SiteUser.IsDeactivated orderby obj.ID descending select obj;
}
}
I've tried several different queries:
I have a VisiblePhotos property:
This wasn't working:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>() where a.Photos.Contains(p) select p;
}
Changed to this:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>() where a.Photos.Any(other => p.ID == other.ID) select p;
}
Still didn't work.
Here is the calling method:
public static List<Photo> GetLatestPhotosByAlbum(Album alb, int count = 3)
{
lock (sync)
{
return alb.VisiblePhotos().OrderByDescending(p => p.ID).Take(count).ToList();
}
}
Wasn't working, changed to this:
public static List<Photo> GetLatestPhotosByAlbum(Album alb, int count = 3)
{
lock (sync)
{
return (from p in VisibleObjects.OfType<Photo>()
where alb.Photos.Any(ph => ph.ID == ph.ID)
select p).ToList();
}
}
Still isn't working. Complaining about not being able to create a constant of my Photo object type, which is an Entity object with an ID property, if it helps. I am not sure of the real cause of the error and I don't have any other ideas of queries in my mind. I think the method name is pretty self explanatory: I'm trying to get the photos in a given album. Loading album entries into memory is not a solution, the query should run on database, not memory. I need an explanation of this exception, why it is occuring here, and how can I get my query to work.
It will not work because you want to use local Album in linq-to-entities query. You must either use navigation property on p to get its album:
var query = from p in VisibleObjects.OfType<Photo>()
where p.Album.Id == alb.Id
select p;
or you must build complex query with some join between photos and albums. You cannot pass local object and any its relation to the query. Only simple properties can be passed.
I think that EF is trying to convert where a.Photos.Contains(p) into SQL like WHERE p IN (a.Photos), but it doesn't know how to express a.Photos in SQL. The SQL you want probably looks like WHERE p.Id IN (1, 2, 3), so you could try doing that in C#:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
var photoIds = a.Photos.Select(p => p.Id).ToArray();
return from p in VisibleObjects.OfType<Photo>() where photoIds.Contains(p.Id) select p;
}
I ran into a similar problem, and instead of IQueryable, I tried using List, and it worked. May be of some help.
I tried another way around and it worked:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>()
where p.Albums.Any(alb => a.ID == alb.ID)
select p;
}
Quite weird to see this works but the other one not. But I'm still wondering why Contains is not working.

How can I pass a Predicate<T> to the Where() method in Linq to SQL?

I have the following model:
+--------+
| Folder |
+--------+
| 1
|
| *
+----------+ +---------+
| WorkItem |---------| Project |
+----------+ * 1 +---------+
I need to retrieve a list of Folders with the current count of WorkItems.
If I have specified a Project, then I only want the count of WorkItems in each Folder that are associated with the specified Project.
If no Project is specified, it should return the total WorkItem count.
I have the following Linq to SQL code:
public interface IWorkItemCriteria {
int? ProjectId { get; }
}
public static IQueryable<Folder> GetFoldersWithItemCounts(IWorkItemCriteria criteria) {
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Count()
};
return(results);
}
The problem is - I want to filter the work items that are being counted.
This works:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(item => item.ProjectId == criteria.ProjectId).Count()
};
but I can't get it to use any kind of dynamic predicate / expression. The syntax I'm trying to use is:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(filter).Count()
};
I've tried
Predicate<WorkItem> filter = (item => item.ProjectId == criteria.ProjectId);
and
Expression<Func<WorkItem, bool>> filter = (item => item.ProjectId == criteria.ProjectId)
neither of which will compile - gives The type arguments for method 'System.Linq.Enumerable.Where<TSource> (System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,bool>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I've tried
Func<WorkItem, bool> filter = (item => item.ProjectId == criteria.ProjectId);
which builds, but then fails with 'Unsupported overload used for query operator 'Where'.'
I'm going to need to add additional properties to the IWorkItemCriteria interface, so the ability to dynamically construct a predicate that can be cleanly translated by Linq to SQL is pretty important.
Any ideas?
I think your problem is that you'd like to reference one expression (filter) from within a second expression (the one being passed to results.Where.Select()), and that the LINQ to SQL IQueryable provider doesn't know how to pull in the value of that.
What you're going to have to do is compose the Select expression from scratch in order to inline the expression that's your dynamic filter. This might be extra hard with anonymous types, i'm not sure. I just found the following article, it seems to explain this pretty well: http://www.codeproject.com/KB/linq/rewrite_linq_expressions2.aspx
Something I grabbed off of MSDN: the idea is that you just point it to an existing function:
using System;
public class GenericFunc
{
public static void Main()
{
Func<string, string> convertMethod = UppercaseString;
}
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
}
I'm sure there are also other ways. I remember doing something like
new Func<WorkItem, bool>((item => item.projectId == criteria.ProjectId))
But I'm not sure. anymore, I'm quite sure you need the "new" though, hope this helps :)

LINQ OrderBy versus ThenBy

Can anyone explain what the difference is between:
tmp = invoices.InvoiceCollection
.OrderBy(sort1 => sort1.InvoiceOwner.LastName)
.OrderBy(sort2 => sort2.InvoiceOwner.FirstName)
.OrderBy(sort3 => sort3.InvoiceID);
and
tmp = invoices.InvoiceCollection
.OrderBy(sort1 => sort1.InvoiceOwner.LastName)
.ThenBy(sort2 => sort2.InvoiceOwner.FirstName)
.ThenBy(sort3 => sort3.InvoiceID);
Which is the correct approach if I wish to order by 3 items of data?
You should definitely use ThenBy rather than multiple OrderBy calls.
I would suggest this:
tmp = invoices.InvoiceCollection
.OrderBy(o => o.InvoiceOwner.LastName)
.ThenBy(o => o.InvoiceOwner.FirstName)
.ThenBy(o => o.InvoiceID);
Note how you can use the same name each time. This is also equivalent to:
tmp = from o in invoices.InvoiceCollection
orderby o.InvoiceOwner.LastName,
o.InvoiceOwner.FirstName,
o.InvoiceID
select o;
If you call OrderBy multiple times, it will effectively reorder the sequence completely three times... so the final call will effectively be the dominant one. You can (in LINQ to Objects) write
foo.OrderBy(x).OrderBy(y).OrderBy(z)
which would be equivalent to
foo.OrderBy(z).ThenBy(y).ThenBy(x)
as the sort order is stable, but you absolutely shouldn't:
It's hard to read
It doesn't perform well (because it reorders the whole sequence)
It may well not work in other providers (e.g. LINQ to SQL)
It's basically not how OrderBy was designed to be used.
The point of OrderBy is to provide the "most important" ordering projection; then use ThenBy (repeatedly) to specify secondary, tertiary etc ordering projections.
Effectively, think of it this way: OrderBy(...).ThenBy(...).ThenBy(...) allows you to build a single composite comparison for any two objects, and then sort the sequence once using that composite comparison. That's almost certainly what you want.
I found this distinction annoying in trying to build queries in a generic manner, so I made a little helper to produce OrderBy/ThenBy in the proper order, for as many sorts as you like.
public class EFSortHelper
{
public static EFSortHelper<TModel> Create<TModel>(IQueryable<T> query)
{
return new EFSortHelper<TModel>(query);
}
}
public class EFSortHelper<TModel> : EFSortHelper
{
protected IQueryable<TModel> unsorted;
protected IOrderedQueryable<TModel> sorted;
public EFSortHelper(IQueryable<TModel> unsorted)
{
this.unsorted = unsorted;
}
public void SortBy<TCol>(Expression<Func<TModel, TCol>> sort, bool isDesc = false)
{
if (sorted == null)
{
sorted = isDesc ? unsorted.OrderByDescending(sort) : unsorted.OrderBy(sort);
unsorted = null;
}
else
{
sorted = isDesc ? sorted.ThenByDescending(sort) : sorted.ThenBy(sort)
}
}
public IOrderedQueryable<TModel> Sorted
{
get
{
return sorted;
}
}
}
There are a lot of ways you might use this depending on your use case, but if you were for example passed a list of sort columns and directions as strings and bools, you could loop over them and use them in a switch like:
var query = db.People.AsNoTracking();
var sortHelper = EFSortHelper.Create(query);
foreach(var sort in sorts)
{
switch(sort.ColumnName)
{
case "Id":
sortHelper.SortBy(p => p.Id, sort.IsDesc);
break;
case "Name":
sortHelper.SortBy(p => p.Name, sort.IsDesc);
break;
// etc
}
}
var sortedQuery = sortHelper.Sorted;
The result in sortedQuery is sorted in the desired order, instead of resorting over and over as the other answer here cautions.
if you want to sort more than one field then go for ThenBy:
like this
list.OrderBy(personLast => person.LastName)
.ThenBy(personFirst => person.FirstName)
Yes, you should never use multiple OrderBy if you are playing with multiple keys.
ThenBy is safer bet since it will perform after OrderBy.

Can I use LINQ to retrieve only "on change" values?

What I'd like to be able to do is construct a LINQ query that retrieved me a few values from some DataRows when one of the fields changes. Here's a contrived example to illustrate:
Observation Temp Time
------------- ---- ------
Cloudy 15.0 3:00PM
Cloudy 16.5 4:00PM
Sunny 19.0 3:30PM
Sunny 19.5 3:15PM
Sunny 18.5 3:30PM
Partly Cloudy 16.5 3:20PM
Partly Cloudy 16.0 3:25PM
Cloudy 16.0 4:00PM
Sunny 17.5 3:45PM
I'd like to retrieve only the entries when the Observation changed from the previous one. So the results would include:
Cloudy 15.0 3:00PM
Sunny 19.0 3:30PM
Partly Cloudy 16.5 3:20PM
Cloudy 16.0 4:00PM
Sunny 17.5 3:45PM
Currently there is code that iterates through the DataRows and does the comparisons and construction of the results but was hoping to use LINQ to accomplish this.
What I'd like to do is something like this:
var weatherStuff = from row in ds.Tables[0].AsEnumerable()
where row.Field<string>("Observation") != weatherStuff.ElementAt(weatherStuff.Count() - 1) )
select row;
But that doesn't work - and doesn't compile since this tries to use the variable 'weatherStuff' before it is declared.
Can what I want to do be done with LINQ? I didn't see another question like it here on SO, but could have missed it.
Here is one more general thought that may be intereting. It's more complicated than what #tvanfosson posted, but in a way, it's more elegant I think :-). The operation you want to do is to group your observations using the first field, but you want to start a new group each time the value changes. Then you want to select the first element of each group.
This sounds almost like LINQ's group by but it is a bit different, so you can't really use standard group by. However, you can write your own version (that's the wonder of LINQ!). You can either write your own extension method (e.g. GroupByMoving) or you can write extension method that changes the type from IEnumerable to some your interface and then define GroupBy for this interface. The resulting query will look like this:
var weatherStuff =
from row in ds.Tables[0].AsEnumerable().AsMoving()
group row by row.Field<string>("Observation") into g
select g.First();
The only thing that remains is to define AsMoving and implement GroupBy. This is a bit of work, but it is quite generally useful thing and it can be used to solve other problems too, so it may be worth doing it :-). The summary of my post is that the great thing about LINQ is that you can customize how the operators behave to get quite elegant code.
I haven't tested it, but the implementation should look like this:
// Interface & simple implementation so that we can change GroupBy
interface IMoving<T> : IEnumerable<T> { }
class WrappedMoving<T> : IMoving<T> {
public IEnumerable<T> Wrapped { get; set; }
public IEnumerator<T> GetEnumerator() {
return Wrapped.GetEnumerator();
}
public IEnumerator<T> GetEnumerator() {
return ((IEnumerable)Wrapped).GetEnumerator();
}
}
// Important bits:
static class MovingExtensions {
public static IMoving<T> AsMoving<T>(this IEnumerable<T> e) {
return new WrappedMoving<T> { Wrapped = e };
}
// This is (an ugly & imperative) implementation of the
// group by as described earlier (you can probably implement it
// more nicely using other LINQ methods)
public static IEnumerable<IEnumerable<T>> GroupBy<T, K>(this IEnumerable<T> source,
Func<T, K> keySelector) {
List<T> elementsSoFar = new List<T>();
IEnumerator<T> en = source.GetEnumerator();
if (en.MoveNext()) {
K lastKey = keySelector(en.Current);
do {
K newKey = keySelector(en.Current);
if (newKey != lastKey) {
yield return elementsSoFar;
elementsSoFar = new List<T>();
}
elementsSoFar.Add(en.Current);
} while (en.MoveNext());
yield return elementsSoFar;
}
}
You could use the IEnumerable extension that takes an index.
var all = ds.Tables[0].AsEnumerable();
var weatherStuff = all.Where( (w,i) => i == 0 || w.Field<string>("Observation") != all.ElementAt(i-1).Field<string>("Observation") );
This is one of those instances where the iterative solution is actually better than the set-based solution in terms of both readability and performance. All you really want Linq to do is filter and pre-sort the list if necessary to prepare it for the loop.
It is possible to write a query in SQL Server (or various other databases) using windowing functions (ROW_NUMBER), if that's where your data is coming from, but very difficult to do in pure Linq without making a much bigger mess.
If you're just trying to clean the code up, an extension method might help:
public static IEnumerable<T> Changed(this IEnumerable<T> items,
Func<T, T, bool> equalityFunc)
{
if (equalityFunc == null)
{
throw new ArgumentNullException("equalityFunc");
}
T last = default(T);
bool first = true;
foreach (T current in items)
{
if (first || !equalityFunc(current, last))
{
yield return current;
}
last = current;
first = false;
}
}
Then you can call this with:
var changed = rows.Changed((r1, r2) =>
r1.Field<string>("Observation") == r2.Field<string>("Observation"));
I think what you are trying to accomplish is not possible using the "syntax suggar". However it could be possible using the extension method Select that pass the index of the item you are evaluating. So you could use the index to compare the current item with the previous one (index -1).
You could useMorelinq's GroupAdjacent() extension method
GroupAdjacent: Groups the adjacent elements of a sequence according to
a specified key selector function...This method has 4 overloads.
You would use it like this with the result selector overload to lose the IGrouping key:-
var weatherStuff = ds.Tables[0].AsEnumerable().GroupAdjacent(w => w.Field<string>("Observation"), (_, val) => val.Select(v => v));
This is a very popular extension to default Linq methods, with more than 1M downloads on Nuget (compared to MS's own Ix.net with ~40k downloads at time of writing)

Resources